在Web Api 2中,控制器上的方法可以具有从URI提供的许多参数,例如,字符串转换为int,如果字符串无法转换为int,则返回自动Web错误消息。
我想对自定义类型执行相同的操作。我创建了一个只包含DateTime对象的类,我想将Web URI字符串参数自定义转换为此DateTime对象。为此,我实现了一个TypeConverter。有用。我的问题是,如果我给它一个错误的日期字符串,我没有web错误,我的方法得到一个空指针。这是我使用typeconverter的模型:
[TypeConverter(typeof(DkDateTimeConverter))]
public class DkDateTime
{
private static readonly ILog log4 = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public DateTime dkDateTime;
public static bool TryParse(string s, out DkDateTime result)
{
log4.Debug("TryParse");
result = null;
var culture = new CultureInfo("da");
try
{
result = new DkDateTime()
{
dkDateTime = DateTime.ParseExact(s, "dd-MM-yyyy HH:mm:ss", culture)
};
return true;
}
catch
{
return false;
}
}
}
class DkDateTimeConverter : TypeConverter
{
private static readonly ILog log4 = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
log4.Debug("CanConvertFrom");
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
log4.Debug("ConvertFrom");
if (value is string)
{
DkDateTime dkDateTime;
if (DkDateTime.TryParse((string)value, out dkDateTime))
{
return dkDateTime;
}
else
{
log4.Debug("Exception");
throw new NotSupportedException();
}
}
return base.ConvertFrom(context, culture, value);
}
}
我的控制器将此方法作为切入点:
public IHttpActionResult Get(Guid messageid, int statuscode, DkDateTime sentdate, DkDateTime donedate)
我的印象是,如果ConvertFrom导致异常,这将由web api反映,并且Web错误消息将被发送回调用者。如果我将“2a”作为状态代码,我会收到这样的网页错误:
<Error>
<Message>The request is invalid.</Message>
</Error>
如何使用我的typeconverter触发相同的错误消息?也许一个转换器无法帮助,但我应该以哪种方式看待?
答案 0 :(得分:2)
你在做什么是正确的,这是设计的。想想您对Guid
param中无效messageid
的期望。同样的事发生在那里。路线不匹配或您收到无效请求。为了更好地控制模型状态验证&amp;您应该从IModelBinder
继承并生成自定义DkDateTimeModelBinder
的错误消息。
查看此帖子:Parameter Binding in ASP.NET Web API
使用示例进行更新。
public class DkDateTime
{
public DateTime dkDateTime;
public static bool TryParse(string s, out DkDateTime result) {
result = null;
var dateTime = default(DateTime);
if (DateTime.TryParseExact(s, "dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime)) {
result = new DkDateTime { dkDateTime = dateTime };
return true;
}
return false;
}
}
public class DkDateTimeModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) {
if (bindingContext.ModelType != typeof(DkDateTime)) {
return false;
}
ValueProviderResult val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (val == null) {
return false;
}
string key = val.RawValue as string;
if (key == null) {
bindingContext.ModelState.AddModelError(
bindingContext.ModelName, "Wrong value type");
return false;
}
DkDateTime result;
if (DkDateTime.TryParse(key, out result)) {
bindingContext.Model = result;
return true;
}
bindingContext.ModelState.AddModelError(
bindingContext.ModelName, "Cannot convert value to DkDateTime");
return false;
}
}
然后在控制器中:
public class ExampleController : ApiController
{
[Route("test")]
public async Task<IHttpActionResult> GetDk([ModelBinder(typeof(DkDateTimeModelBinder))]DkDateTime sendDate) {
if (!ModelState.IsValid) {
return BadRequest(ModelState);
}
return Ok(sendDate);
}
}
现在,当我使用网址http://localhost:4814/example/test?senddate=dsfasdafsd
进行测试时,我会在
状态400错误请求
{
"Message": "The request is invalid.",
"ModelState": {
"sendDate": [
"Cannot convert value to DkDateTime"
]
}
}