[英]Web Api 2: Custom parameter validation (typeconverter)
在Web Api 2中,控制器上的方法可以具有多個從URI提供的參數,例如,將字符串轉換為int,如果無法將字符串轉換為int,則返回自動Web錯誤消息。
我想對自定義類型做同樣的事情。 我創建了一個僅包含DateTime對象的類,並且想要將Web URI字符串參數自定義轉換為該DateTime對象。 為此,我實現了TypeConverter。 有用。 我的問題是,如果給它一個錯誤的日期字符串,則不會出現任何Web錯誤,並且我的方法將得到一個空指針。 這是我的帶有類型轉換器的模型:
[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觸發相同的錯誤消息? 也許類型轉換器不能幫助您,但是我應該怎么看?
您正在執行的操作是正確的,這是設計使然。 想一想您對messageid
參數中的無效Guid
會有什么期望。 同樣的事情在那里發生。 路由不匹配,或者您收到的請求無效。 為了更好地控制模型狀態驗證和錯誤消息,您應該繼承IModelBinder
並構建自定義DkDateTimeModelBinder
。
檢查這篇文章: 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);
}
}
現在,當我使用url http://localhost:4814/example/test?senddate=dsfasdafsd
我在下面得到了預期的http://localhost:4814/example/test?senddate=dsfasdafsd
狀態400錯誤的請求
{
"Message": "The request is invalid.",
"ModelState": {
"sendDate": [
"Cannot convert value to DkDateTime"
]
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.