ASP.NET MVC:数据注释验证是否足够?

我在ASP.NET MVC 2中广泛使用了Data Annotation验证。这个新特性节省了大量时间,因为我现在可以在一个地方定义客户端验证和服务器端验证。 但是,在我进行一些详细的测试时,我意识到如果我单独依赖数据注释验证,则有人可以轻松绕过服务器端验证。 例如,如果我通过使用[Required]属性注释属性来定义必填字段,并将该必填字段的文本框放在表单中,则用户可以简单地从DOM中移除文本框(可以通过Firebug轻松完成)现在在Controller内部的ModelBinding期间,Data Annotation验证不会在该属性上触发。 为了确保“必需的”验证被触发,我可以在ModelBinding发生后重复验证,但是之后我会重复验证逻辑。

每个人对验证的建议是什么? 数据注释验证是否足够? 还是需要重复验证以确保验证在所有情况下都被触发?

后续评论:基于下面的答案,似乎我不能仅依赖于模型绑定器和数据注释验证。 既然我们认为需要额外的服务器端验证,那么是否有一种简单的方法让我的服务层根据数据注释中定义的内容触发验证? 看起来,这会使我们得到两个词中最好的一个......我们不需要重复验证代码,但是即使Model Binder没有触发它,我们仍然会确保验证得到执行。

我将把这个后续评论作为一个单独的问题发布,因为它提出了与原始问题不同的问题。


我认为要对安全性保持警惕,您应该选择让服务器验证成为优先事项,并确保这一切始终是您的后顾之忧。 您的服务器验证应该无需客户端验证即可运行 客户端验证更适用于用户体验,对您的设计至关重要,这对安全性而言是次要的。 考虑到这一点,你会发现自己重复你的验证。 目标经常试图设计您的应用程序,以便尽可能集成服务器和客户端验证,以减少验证服务器和客户端所需的工作。 但请放心,你必须同时做这两件事。

如果绕过客户端验证(通过DOM操作)避免了服务器验证(您似乎指出了这一点),那么您的服务器对此实例的验证可能无法适当使用。 您应该在控制器操作或服务层中再次调用服务器验证。 你描述的场景不应该破坏你的服务器验证。

用你描述的场景,DataAnnotation属性方法应该足够了。 看起来你只需要进行一些代码更改,以确保在提交表单时也可以调用服务器验证。


我将xVal与DataAnnotations配对,并编写了自己的Action过滤器,用于检查任何实体类型参数以进行验证。 因此,如果回发中缺少某个字段,则此验证程序将填充ModelState字典,因此模型无效。

先决条件:

  • 我的实体/模型对象都实现了声明Validate()方法的IObjectValidator接口。
  • 我的属性类叫做ValidateBusinessObjectAttribute
  • xVal验证库
  • 操作筛选器代码:

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        IEnumerable<KeyValuePair<string, object>> parameters = filterContext.ActionParameters.Where<KeyValuePair<string, object>>(p => p.Value.GetType().Equals(this.ObjectType ?? p.Value.GetType()) && p.Value is IObjectValidator);
        foreach (KeyValuePair<string, object> param in parameters)
        {
            object value;
            if ((value = param.Value) != null)
            {
                IEnumerable<ErrorInfo> errors = ((IObjectValidator)value).Validate();
                if (errors.Any())
                {
                    new RulesException(errors).AddModelStateErrors(filterContext.Controller.ViewData.ModelState, param.Key);
                }
            }
        }
    }
    

    我的控制器动作是这样定义的:

    [ValidateBusinessObject]
    public ActionResult Register(User user, Company company, RegistrationData registrationData)
    {
        if (!this.ModelState.IsValid)
        {
            return View();
        }
        ...
    }
    

    DataAnnotation肯定是不够的。 我广泛使用它来预先验证我对域模型的调用,以获得更好的错误报告并尽早失败。

    但是,您可以自己调整DataAnnotation模型以确保必须发布[必需的]属性。 (将在今天晚些时候跟进代码)。

    更新获取DataAnnotations Model Binder的源代码并在DataAnnotationsModelBinder.cs中找到此行

    // Only bind properties that are part of the request
    if (bindingContext.ValueProvider.DoesAnyKeyHavePrefix(fullPropertyKey)) {
    

    将其更改为

    // Only bind properties that are part of the request
    bool contextHasKey = bindingContext.ValueProvider.DoesAnyKeyHavePrefix(fullPropertyKey);
    bool isRequired = GetValidationAttributes(propertyDescriptor).OfType<RequiredAttribute>().Count() > 0;
    if (contextHasKey || (!contextHasKey && isRequired)) {
    
    链接地址: http://www.djcxy.com/p/56585.html

    上一篇: ASP.NET MVC: Is Data Annotation Validation Enough?

    下一篇: Custom model validation of dependent properties using Data Annotations