2016-04-15 11 views
2

Я пытаюсь найти, есть ли способ, доступный в FluentValidation, который позволяет проверять коллекцию для валидатора на уровне корня.Должен ли я создать новый тип для коллекции в FluentValidation?

См., Например, Как показано ниже, валидатор доступен для CustomerValidator для класса Customer. с использованием FluentValidation;

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; 

Вопрос заключается в том, если у меня есть List<Customer> и мне нужно, чтобы проверить, что по крайней мере один клиент должен иметь Surname Как проверить список. Есть ли вне коробки функциональность, доступная в fluentvalidation, в настоящее время я могу думать о любом из следующих способов. Можете ли вы предложить, какой может быть наилучший подход?

1. Итерация в цикле, а затем вызов метода проверки для каждого Клиента.

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 класс

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

Помимо вышеперечисленного 2 методы, Джереми Скиннер предложил другой метод here, который использует наследование от AbstractValidator<List<Customer>>. Это не работало с исходным кодом, но Джереми совершил изменение в исходном коде Fluent Validation в версии 6.3 here.

Следующий код представляет 3-й способ для проверки правильности набора Root Level.

public class CustomerCollectionValidator : AbstractValidator<List<Customer>> { 
    public CustomerCollectionValidator() { 
    RuleFor(list => list).SetCollectionValidator(new CustomerValidator()); 
    } 
} 
Смежные вопросы