2016-04-15 7 views
2

FluentValidationで利用可能な方法があるかどうかを調べると、ルートレベルのバリデータに対してコレクションの検証が可能になります。FluentValidationでコレクションの新しいタイプを作成する必要がありますか?

以下に示すように、Customerの場合、バリデーターはCustomerValidatorです。 FluentValidationを使用している 。私はList<Customer>を持っていると私は少なくとも1人の顧客は、私はリストを検証しない方法Surnameを持つべきであることを確認する必要がある場合は

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.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 
    } 
} 

Customer customer = new Customer(); 
CustomerValidator validator = new CustomerValidator(); 
ValidationResult results = validator.Validate(customer); 

bool validationSucceeded = results.IsValid; 
IList<ValidationFailure> failures = results.Errors; 

質問は、です。 Fluentvalidationで利用可能な機能のうち、すぐれたものがありますか?現時点では、次のいずれかの方法を考えることができます。 あなたは何が最良の方法であるとお考えですか?

1.ループ内で反復処理を行い、各顧客に対してvalidateメソッドを呼び出します。

List<ValidationResult> listOfValidationErrors = List<ValidationResult>(); 
// listCustomer is of type List<Customer> 
foreach (var customer in listCustomer) 
{ 
    CustomerValidator validator = new CustomerValidator(); 
    listOfValidationErrors.Add(validator.Validate(customer); 
} 

2.カスタマー・コレクションCustomerCollectionのための新しいコレクションクラスを作成し、CustomerCollectionValidator

public class CustomerCollection 
    { 
     public List<Customer> ListOfCustomers { get; set; } 

     public CustomerCollection(List<Customer> listOfCustomers) 
     { 
      this.ListOfCustomers = listOfCustomers ; 
     } 
    } 

、その後、Validatorクラス

別に上記2から
public class CustomerCollectionValidator: CompositeValidator<CustomerCollection> 
    { 
     public CustomerCollectionValidator() 
     { 

      RuleFor(x => x.ListOfCustomers) 
        .Must(ShouldHaveOneSurName) 
        .WithMessage("Should have one Surname in list"); 

      RuleForEach(x => x.ListOfCustomers).SetValidator<CustomerValidator>(); 

     } 

     public bool ShouldHaveOneSurName(List<Customer> lstCustomers) 
     { 
      if (lstCustomers== null) 
      { 
       return false; 
      } 
      return lstCustomers.Any(x => !String.IsNullOrWhiteSpace(x.SurName); 
     } 


    } 

答えて

2

をバリデータクラスを作成しますメソッド、ジェレミースキナーは、別の方法を提案here、継承を使用してAbstractValidator<List<Customer>>。これは元のコードでは機能しませんでしたが、Jeremyはバージョン6.3のFluent Validationソースコードの変更をコミットしましたhere

次のコードは、ルートレベルコレクションの検証を行う3番目の方法を示しています。

public class CustomerCollectionValidator : AbstractValidator<List<Customer>> { 
    public CustomerCollectionValidator() { 
    RuleFor(list => list).SetCollectionValidator(new CustomerValidator()); 
    } 
} 
関連する問題