C# 如何使用DataAnnotation强制执行例如数值约束?

C# 如何使用DataAnnotation强制执行例如数值约束?,c#,validation,asp.net-web-api,data-annotations,C#,Validation,Asp.net Web Api,Data Annotations,我试图利用模型状态来验证对WebAPI的请求,但在如何控制某些属性的错误消息方面遇到了一些问题。例如,给定以下模型 public class Stuff { [Range(0, Double.PositiveInfinity)] public double? SomeProp { get; set; } } (以及在文章底部定义的一些基础设施)具有有效负载的请求(例如{someProp:“1.2”}将正确绑定模型-负值或缺失值将给出错误-但是如果我输入的不是有效数字的内容(

我试图利用模型状态来验证对WebAPI的请求,但在如何控制某些属性的错误消息方面遇到了一些问题。例如,给定以下模型

public class Stuff {

    [Range(0, Double.PositiveInfinity)]
    public double? SomeProp { get; set; }

}
(以及在文章底部定义的一些基础设施)具有有效负载的请求(例如
{someProp:“1.2”}
将正确绑定模型-负值或缺失值将给出错误-但是如果我输入的不是有效数字的内容(例如
{someProp:“hello”}
),模型状态将出现错误,例如

将值“hello”转换为类型“System.Nullable`1[System.Double]”时出错。路径“某物”,第1行,位置41

(我猜位置在JSON对象中,这里是从一个更大的请求中切下来的,所以不介意确切的数字…)。对于另一个不可为null但具有
[Required]
属性的属性,除了上述消息之外,模型状态dict中还包含有关缺少必需属性的错误消息

我确实理解为什么
“hello”
不能绑定到
双精度?
(或
双精度
),但不管我在属性中设置了什么约束,似乎在检查它们之前,该值必须是模型绑定的,如果模型绑定失败,我都会得到上面不太友好的消息,以及值未设置时应用的所有其他错误。在尝试绑定值之前,我能够应用的唯一约束是正则表达式,但如果失败,我会收到类似的用户不友好消息,如

字段SomeProp必须与正则表达式“”匹配

有没有办法解决这个问题,这样当我在文本框中输入非数字的内容时,我可以给用户一个更好的错误消息,该文本框应该指定一个数字值

脚注:我的验证基础架构 其中,
Validate
属性定义如下:

public class ValidationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            actionContext.Response = actionContext.Request
                .CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}

不久前,我还在为同样的概念而挣扎。这是我发现的,非常简单。MVC在控制器的操作方法调用之前调用验证例程。这就是ModelState.IsValid工作的原因。但这里有一个陷阱,有两个验证级别1)dataannotations级别和2)ViewModel或Model中IValidatableObject的实现。您可以关闭模型注释,并在模型中实现IValidatableObject,以便对验证进行100%的控制。它只有一个方法,您可以使用Yeild返回ValidationResults。所有属性都在那里。@user1522548:感谢您提供有关
IValidatableObject
的提示,但在这种情况下,它对我没有帮助。在请求生命周期中,验证似乎发生得太晚,无法解决我所描述的那种问题(即首先无法绑定模型的格式不正确的输入)。好的,这意味着只有一件事,您必须在客户端进行验证,因为数据注释似乎让您失败。当你说现在已经太晚了,这告诉我MVC中的Ajax验证工作正在出错。@user1522548:我在这里没有用MVC做任何事情-这是在WebAPI中。我试图实现的是通过XHR实现客户端验证,以避免有多个规则集,所以我真的希望避免在客户端上进行额外的验证。明白了。看看这个类似问题的解决方案。。
public class ValidationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            actionContext.Response = actionContext.Request
                .CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}