FluentValidation v3: Conditional validation of collection elements

This is part 5 in a series of posts about new features in FluentValidation v3.

FluentValidation has supported validation of collection properties since v1.1. By using a child validator, you can indicate that each element in a collection should be validated:

public class Person {
  public List<Order> Orders { get; set; }
}
 
public class Order {
  public decimal? Amount { get; set; }
}
 
public class OrderValidator : AbstractValidator<Order> {
  public OrderValidator() {
     RuleFor(x => x.Amount).GreaterThan(0);
  }
}
 
public class PersonValidator : AbstractValidator<Person> {
  public PersonValidator() {
    RuleFor(x => x.Orders).SetValidator(new OrderValidator());
  }
}

With FluentValidation v3, you can now apply a condition to collection validators to indicate only certain items in the collection should be validated. To achieve this, FluentValidation v3 has a new “SetCollectionValidator” method which exposes an additional “Where” method in the fluent interface. It was necessary to introduce this extra method to differentiate SetValidator calls that are setting a child validator for the entire property from those that are validating collection elements.

Using the new feature, we could now only validate those Orders whose Amount is not null:

public class PersonValidator : AbstractValidator<Person> {
  public PersonValidator() {
    RuleFor(x => x.Orders).SetCollectionValidator(new OrderValidator())
        .Where(x => x.Amount != null);
  }
}