【问题标题】:How do you validate against each string in a list using Fluent Validation?如何使用 Fluent Validation 对列表中的每个字符串进行验证?
【发布时间】:2012-04-17 11:26:16
【问题描述】:

我有一个 MVC3 视图模型定义为:

[Validator(typeof(AccountsValidator))]
public class AccountViewModel
{
    public List<string> Accounts { get; set; }
}

使用 FluentValidation (v3.3.1.0) 定义的验证为:

public class AccountsValidator : AbstractValidator<AccountViewModel>
{
    public AccountsValidator()
    {
        RuleFor(x => x.Accounts).SetCollectionValidator(new AccountValidator()); //This won't work
    }
}

并且可能会定义帐户验证:

public class AccountValidator : AbstractValidator<string> {
    public OrderValidator() {
        RuleFor(x => x).NotNull();
        //any other validation here
    }
}

我希望列表中的每个帐户都按照documentation 中的说明进行验证。但是,对SetCollectionValidator 的调用不起作用,因为在使用List&lt;string&gt; 时这不是一个选项,尽管如果将其定义为List&lt;Account&gt;,该选项就会出现。我错过了什么吗?我可以更改我的模型以使用 List&lt;Account&gt;,然后定义一个 Account 类,但我真的不想更改我的模型以适应验证。

作为参考,这是我正在使用的视图:

@model MvcApplication9.Models.AccountViewModel

@using (Html.BeginForm())
{
    @*The first account number is a required field.*@
    <li>Account number* @Html.EditorFor(m => m.Accounts[0].Account) @Html.ValidationMessageFor(m => m.Accounts[0].Account)</li>

    for (int i = 1; i < Model.Accounts.Count; i++)
    {
        <li>Account number @Html.EditorFor(m => m.Accounts[i].Account) @Html.ValidationMessageFor(m => m.Accounts[i].Account)</li>
    }

    <input type="submit" value="Add more..." name="add"/>
    <input type="submit" value="Continue" name="next"/>
}

【问题讨论】:

    标签: c# asp.net-mvc-3 fluentvalidation


    【解决方案1】:

    以下应该有效:

    public class AccountsValidator : AbstractValidator<AccountViewModel>
    {
        public AccountsValidator()
        {
            RuleFor(x => x.Accounts).SetCollectionValidator(
                new AccountValidator("Accounts")
            );
        }
    }
    
    public class AccountValidator : AbstractValidator<string> 
    {
        public AccountValidator(string collectionName)
        {
            RuleFor(x => x)
                .NotEmpty()
                .OverridePropertyName(collectionName);
        }
    }
    

    【讨论】:

    • 谢谢,SetCollectionValidator 确实有效。我不太确定为什么以前没有此声明!但是,它仍然不能正常工作。正在使用验证,但现在任何错误都会使用“Accounts[0].Accounts”键写入模型状态。我在视图中使用 ValidationMessageFor(m => m.Accounts[i]) 来显示每个帐号,因此 ModelState 应该有一个“Accounts[0]”键。我尝试使用空白名称更改 OverridePropertyName(collectionName) 并完全删除此语句,但仍然无法使其正常工作。
    • 我可以使用 @Html.ValidationMessage("Accounts[i].Accounts") 让它工作,但这似乎又是一种解决方法?我很欣赏你对此的看法?再次感谢。
    • 我决定使用 Account 模型而不是字符串。因此,现在可以正确报告错误。因此,上述集合名称不需要作为参数。
    • 我希望有一个简写来验证数组中的每个字符串,因为它几乎总是只需要 1 个流利的字符串来验证每个字符串。额外的验证器是样板文件。
    【解决方案2】:

    尝试使用:

    public class AccountsValidator : AbstractValidator<AccountViewModel>
    {
       public AccountsValidator()
       {
           RuleForEach(x => x.Accounts).NotNull()
       }
    }
    

    【讨论】:

      【解决方案3】:

      你可以使用RuleForEach 有一个带有字符串列表的简单类

         public class Request
          {
              public IEnumerable<string> UserIds { get; set; }      
              public string  Body { get; set; }        
          }
      
      

      我创建了下一个验证器

      public class RequestValidator : AbstractValidator<Request>
          {
              public RequestValidator()
              {        
                  RuleForEach(x => x.UserIds).NotNull().NotEmpty();            
                  RuleFor(x => x.Body).NotNull().NotEmpty();      
              }
          }
      

      【讨论】:

        【解决方案4】:

        验证类:

        using FluentValidation;
        using System.Collections.Generic;
        
        namespace Test.Validator
        {
        
            public class EmailCollection
            {
                public IEnumerable<string> email { get; set; }
        
            }
        
            public class EmailValidator:  AbstractValidator<string>
            {
                public EmailValidator()
                {
                    RuleFor(x => x).Length(0, 5);
                }
        
            }
        
            public class EmailListValidator: AbstractValidator<EmailCollection>
            {
                public EmailListValidator()
                {
                    RuleFor(x => x.email).SetCollectionValidator(new EmailValidator());
                }
        
            }
        
        
        
        }
        

        注意:我使用了最新的 MVC 5 (Nuget) 版本的 fluentvalidation。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-19
          • 1970-01-01
          • 2011-12-26
          • 1970-01-01
          • 2013-03-16
          • 1970-01-01
          • 2015-11-05
          • 1970-01-01
          相关资源
          最近更新 更多