通过设置不同的RuleSet,对复杂子对象进行流畅验证

时间:2013-06-18 21:35:32

标签: asp.net-mvc validation asp.net-mvc-4 fluent fluentvalidation

我有一个复杂的类结构如下。

public class Account
{ 
   public List<Name> Person {get;set;}
   public List<Address> Address {get;set;}
   public string Email   {get;set;}
   public string ConfirmEmail {get;set;}
}

public class Name 
{
  public string FirstName {get; set;}
  public string LastName {get;set;}
  public string DateOfBirth {get;set;}
  public string SSN {get;Set;}
}

public class Address 
{
  public string AddressLine1 {get;set;}
  public string AddressLine2 {get;set;}
  public string City {get;set;}
  public string State {get;set;}
}

以下是验证器

public class AccountValidator : AbstractValidator<Account>
{
  public AccountValidator()
  {
    RuleSet("Account", () =>
    { 
     RuleFor(account => account.Person).SetCollectionValidator(new NameValidator());
     RuleFor(account => account.Address).SetCollectionValidator(new AddressValidator());
   });
     }
   }
  }


public class NameValidator : AbstractValidator<Name>
 {
    public NameValidator()
     {
        RuleSet("Account", () =>
        {
            SharedRules();
        });

        RuleSet("Name_DateOfBirth", () =>
        {
          SharedRules();
          RuleFor(name => name.DateOfBirth).NotEmpty());
        });
    }

     void SharedRules()
    {
      RuleFor(name => name.FirstName).NotEmpty());
      RuleFor(name => name.FirstName).Length(1, 20));
      RuleFor(name => name.LastName).NotEmpty());
      RuleFor(name => name.LastName).Length(1, 20));
      }
 }
public class AddressValidator : AbstractValidator<Address>
{
  public AddressValidator()
  {
    RuleSet("Account", () =>
    {
      SharedRules();
     });
  }

    void SharedRules()
    {

        RuleFor(address => address.AddressLine1).NotEmpty());
        ... 
        .... etc..
    }
 }

我有[HttpPost] ActionMethod如下: -

[HttpPost]
public ActionResult Register([CustomizeValidator(RuleSet="Account")] Account model)
 {
    if(MoelState.IsValid)
    {
        //blah blah
    }
    else 
    {
      //blah blah
    }
 }

我对注册表的看法如下: -

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "Register" }))
{
   @Html.AntiForgeryToken();   
   <h1>Register</h1>    
   @Html.ValidationSummary(false)
   <div id="divName">   
     @Html.EditorFor(m => m.Person[0])
   </div>
      for (int i = 0; i < 2; i++)
     {
        if (i == 0)
       {  
        <div id="divHomeAdd">
            @Html.EditorFor(m => m.Address[0])
        </div>       
       <input type="checkbox"/>   
       <label for="nohomeaddress"> Do not Have Home Address </label>
       }
        if (i == 1)
      { 
        <div id="divMailingAdd">
            @Html.EditorFor(m => m.Address[1])
        </div>
        }
      }

    @Html.TextBoxCustomFor(m => m.Email)   
    @Html.TextBoxCustomFor(m => m.ConfirmEmail) 
    <input type="submit" value="Register" id="btnRegister" name="Register" />
 }

我必须显示EditorFor()Name,但只需要FirstName和LastName,即需要在NameValidator中为“Account”触发RuelSet。

对于其他一些视图我需要激活“Name_DateOfBirth”RuleSet,因为该屏幕需要出生日期作为必填字段以及普通的名字和姓氏。如何在MVC中做到这一点?

如果选中“无家庭地址”复选框,则必须显示家庭地址验证,然后才需要验证邮件地址属性。

如何在这种情况下使用RuleSet?我们是否需要在父母和子女中拥有相同的规则名称?即“帐户”规则应该存在于AccountValidator和NameValidator中,以便它可以触发吗?

1 个答案:

答案 0 :(得分:1)

到目前为止你所看到的是一个好的开始。使用视图名称作为规则集名称是一个好主意,因为您将在视图上的哪些字段与哪些字段得到验证之间具有良好的关系。

我唯一注意到的是你错过了模型类的ValidatorAttribute装饰。

Here是一些很好的文档,如果你还没有看到它。

相关问题