This example demonstrating how to conditionally validate nested objects using FluentValidation’s When method.
Scenario
Let’s say we have:
- A Personclass with anAddressproperty
- We only want to validate the AddresswhenHasAddressistrue
Model Classes
public class Person
{
    public string Name { get; set; }
    public bool HasAddress { get; set; }
    public Address Address { get; set; }
}
public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public string ZipCode { get; set; }
}Validator Implementation
public class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator()
    {
        // Always validate name
        RuleFor(x => x.Name).NotEmpty().MaximumLength(100);
        
        // Only validate address when HasAddress is true
        When(x => x.HasAddress, () => 
        {
            RuleFor(x => x.Address)
                .NotNull()
                .WithMessage("Address must be provided when HasAddress is true");
                
            RuleFor(x => x.Address.Street)
                .NotEmpty()
                .When(x => x.Address != null)
                .WithMessage("Street is required");
                
            RuleFor(x => x.Address.City)
                .NotEmpty()
                .When(x => x.Address != null)
                .MaximumLength(50);
                
            RuleFor(x => x.Address.ZipCode)
                .NotEmpty()
                .When(x => x.Address != null)
                .Matches(@"^\d{5}(-\d{4})?$");
        });
    }
}Alternative Approach (Using Child Validator)
public class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator()
    {
        RuleFor(x => x.Name).NotEmpty().MaximumLength(100);
        
        When(x => x.HasAddress, () => 
        {
            RuleFor(x => x.Address)
                .NotNull()
                .SetValidator(new AddressValidator());
        });
    }
}
public class AddressValidator : AbstractValidator<Address>
{
    public AddressValidator()
    {
        RuleFor(x => x.Street).NotEmpty();
        RuleFor(x => x.City).NotEmpty().MaximumLength(50);
        RuleFor(x => x.ZipCode).NotEmpty().Matches(@"^\d{5}(-\d{4})?$");
    }
}Usage Example
var person = new Person 
{
    Name = "Khan",
    HasAddress = false,
    Address = null
};
var validator = new PersonValidator();
var result = validator.Validate(person); // Won't validate addressKey Points:
- The Whencondition determines whether the nested rules should execute
- The nested rules are only evaluated if HasAddressis true
- We still need null checks for the address object itself
- The second approach using a separate validator is cleaner for complex nested objects
This pattern is useful when you want to validate complex objects only in certain scenarios, reducing unnecessary validation overhead.

 Add to favorites
Add to favorites