2016-07-19 36 views
0

我验证使用ModelState.IsValid输入:为空类型无效的ModelState错误消息

[HttpGet] 
[Route("subjects")] 
[ValidateAttribute] 
public IHttpActionResult GetSubjects(bool? isActive = null) 
{ 
    //get subjects 
} 

如果我通过在URI ~/subjects/?isActive=abcdef,我得到的错误消息:

值“ABCDEF”是对于Nullable`1无效。

如果输入参数不能为空

public IHttpActionResult GetSubjects(bool isActive){ 
    //get subjects 
} 

我得到的错误信息:

值 'ABCDEF' 不是有效的布尔值。

我想重写消息如果可为空的类型,所以我可以维护消息(“值'abcdef'是无效的布尔。”)。我怎么能这样做,因为在ModelState错误我没有得到数据类型。我正在实施验证作为自定义ActionFilterAttributeValidationAttribute)。

+0

你可以设置你'ModelState'想要的任何错误消息。 – lorond

+0

我可以将它设置为我想要的样子“值'abcdef'对于布尔值无效”,但问题是错误对象没有被验证参数的类型信息(bool,int等)。 – alltej

回答

2

您可以更改格式类型转换错误消息的回调。例如,让我们把它定义为权Global.asax.cs

public class WebApiApplication : HttpApplication 
{ 
    protected void Application_Start() 
    { 
     ModelBinderConfig.TypeConversionErrorMessageProvider = this.NullableAwareTypeConversionErrorMessageProvider; 

     // rest of your initialization code 
    } 

    private string NullableAwareTypeConversionErrorMessageProvider(HttpActionContext actionContext, ModelMetadata modelMetadata, object incomingValue) 
    { 
     var target = modelMetadata.PropertyName; 
     if (target == null) 
     { 
      var type = Nullable.GetUnderlyingType(modelMetadata.ModelType) ?? modelMetadata.ModelType; 
      target = type.Name; 
     } 

     return string.Format("The value '{0}' is not valid for {1}", incomingValue, target); 
    } 
} 

对于非可空类型Nullable.GetUnderlyingType将返回null,在这种情况下,我们会使用原始类型。

不幸的是,你不能访问默认的字符串资源,如果你需要本地化错误信息,你必须自己做。

另一种方法是实现您自己的IModelBinder,但这不是您的特定问题的好主意。

0

Lorond的回答突出了如何灵活地使用asp.net web api来让程序员自定义API的许多部分。当我看到这个问题时,我的思考过程是在一个动作过滤器中处理它,而不是覆盖配置中的某些东西。

public class ValidateTypeAttribute : ActionFilterAttribute 
{ 
    public ValidateTypeAttribute() { } 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     string somebool = actionContext.Request.GetQueryNameValuePairs().Where(x => x.Key.ToString() == "somebool").Select(x => x.Value).FirstOrDefault(); 

     bool outBool; 
     //do something if somebool is empty string 
     if (!bool.TryParse(somebool, out outBool)) 
     { 
      HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest); 
      response.ReasonPhrase = "The value " + somebool + " is not valid for Boolean."; 
      actionContext.Response = response; 
     } 
     else 
     { 
      base.OnActionExecuting(actionContext); 
     } 
    } 

然后装点操作方法与动作过滤器控制器属性

+0

“somebool”在这里被硬编码。因为它将是一个属性,我需要在不同的控制器中大量使用,我们不知道参数名称和可空参数类型(bool?,int?),所以我不能硬编码参数名称和类型。 – alltej

+0

你可以绕过一个类型测试。 – Bill

相关问题