【问题标题】:How do I do complex model validations in an ASP.NET MVC 2 application?如何在 ASP.NET MVC 2 应用程序中进行复杂的模型验证?
【发布时间】:2012-09-21 16:55:20
【问题描述】:

一段时间以来,我一直在努力重构我如何进行模型验证。我的应用程序都是 ASP.NET MVC 2(.Net 3.5 框架)。我已经阅读了这个主题的相关问题,它们与我所问的并不完全相同。

目前,对于页面验证,我通常坚持使用 if/else 语句的大杂烩。问题是,如果字段 A 是某个值,有时会验证字段 B,但字段 A 也有自己的验证。在某些情况下,会有一些角色发挥作用,这也可能会根据用户的角色进行验证(即不验证具有角色 x 的用户无法修改的字段)。

我的问题归结为:

1) 如何以更易于阅读的方式处理验证?我已经查看了 DataAnnotations,但它们还不够。数据注释处理字段值的验证,因为可能需要完成的验证取决于字段的值和对象上其他属性的值。

2) 如何将验证框架与 ASP.NET MVC 2 集成?

我真正讨厌我现在进行验证的方式是,当我添加模型错误时,我正在硬编码该属性的密钥。这很糟糕。不过,我不确定如何获取所述属性的密钥,使其与 html 助手创建的 html 字段匹配。

例如,在我看来,我正在使用编辑器模板来显示我的客户对象的字段。

   <%= Html.EditorFor(m => m.CustomerInfo) %>

生成的部分 html 为 FirstName 创建字段:

<input id="CustomerInfo_FirstName" name="CustomerInfo.FirstName" style="width:330px;" type="text" value="John" />

为了让框架仍然使用必要的 CSS 突出显示该字段,我强制执行此验证,如下所示:

//Ignore that this can be done with DataAnnotations. This is just a simple example.   
if (String.IsnullOrEmpty(customerInfo.FirstName) )
{
    ModelState.AddModelError("CustomerInfo.FirstName",
    "First Name is required.");
}

这是我认为的主要问题。我没有很好的方法来知道页面上字段的名称。好像采取了

的模式
 <objectname>.<propertyname>

,但我真的想要更可靠的东西。

要获取对象名称,我想我可以将它从 ModelBindingContext 类中拉出来,但我不确定如何从控制器内部获取它的实例。对于属性名称,我可以使用某种 lambda,它将属性名称作为字符串返回。

总而言之,我正在寻找:1) 某种允许复杂验证的验证框架 2) 某种方法来识别在 ModelState.AddModelError 方法中使用的密钥,这样 MVC 的错误样式仍然有效。

【问题讨论】:

    标签: c# asp.net-mvc validation asp.net-mvc-2


    【解决方案1】:

    你真的在找FluentValidation

    但是,我不确定它是否支持 MVC2。它确实支持 MVC3 和 MVC4。

    来自其网站的示例代码:

    public class CustomerValidator: AbstractValidator<Customer> {
      public CustomerValidator() {
        RuleFor(customer => customer.Surname).NotEmpty();
        RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
        RuleFor(customer => customer.Company).NotNull();
        RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
        RuleFor(customer => customer.Address).Length(20, 250);
        RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
      }
    
      private bool BeAValidPostcode(string postcode) {
        // custom postcode validating logic goes here
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多