FluentValidation Rule Sets

Introduction Learn how to use rule sets which allow developers to group validation rules together which can be executed together as a group whilst ignoring other rules or execute all rules. The conventional use of Fluent Validation is to create a model followed by creating a validator class. In the example below, each property has there own validator class which allows reuse. public class PersonValidator : AbstractValidator { public PersonValidator() { Include(new IdentifierValidator()); Include(new FirstNameValidator()); Include(new LastNameValidator()); Include(new BirthDateValidator()); Include(new AddressValidator()); Include(new EmailValidator()); } } Sample property validator for FirstName property. public class FirstNameValidator : AbstractValidator { public FirstNameValidator() { RuleFor(person => person.FirstName) .NotEmpty() .MinimumLength(3); } } Using conventional validation works great the majority of work for validation. There are times when not all properties require validations like when adding a new record for EF Core which assigns an identifier. Rule sets Rules sets are setup as shown below where FirstName and LastName are a group while other properties are setup separately. This means that rules can be included or excluded for validating an object. public class PersonValidator : AbstractValidator { public PersonValidator() { RuleSet("Names", () => { RuleFor(x => x.FirstName).NotNull(); RuleFor(x => x.LastName).NotNull(); }); RuleSet("Identifier", () => { RuleFor(x => x.PersonId).NotEqual(0); }); RuleSet("Birth", () => { RuleFor(x => x.BirthDate).BirthDateRule(); }); RuleSet("Email", () => { RuleFor(x => x.EmailAddress).NotEmpty().EmailAddress(); }); } } Example to exclude the Identifier rule. var validator = new PersonValidator(); ValidationResult result = validator.Validate(MockedData.InvalidPerson, options => options.IncludeRuleSets( "Names", "Birth")); if (result.IsValid) { Console.WriteLine("Validation succeeded."); } else { foreach (var error in result.Errors) { AnsiConsole.MarkupLine($"{error.PropertyName,-14} [red]Error:[/] {error.ErrorMessage}"); } } Example to include all rules Using the wildcard indicates to include all rules. var validator = new PersonValidator(); // Use wildcard to include all rule sets var result = validator.Validate( MockedData.InvalidPerson, options => options.IncludeRuleSets("*")); if (result.IsValid) { Console.WriteLine("Validation succeeded."); } else { foreach (var error in result.Errors) { AnsiConsole.MarkupLine($"{error.PropertyName,-14} [red]Error:[/] {error.ErrorMessage}"); } } Source code Provides code samples using mocked data to try out rule sets. Console project Summary Rule sets open up possibilities not only for validation in applications but also for test projects. See also FluentValidation tips C#

Jun 15, 2025 - 23:20
 0
FluentValidation Rule Sets

Introduction

Learn how to use rule sets which allow developers to group validation rules together which can be executed together as a group whilst ignoring other rules or execute all rules.

The conventional use of Fluent Validation is to create a model followed by creating a validator class. In the example below, each property has there own validator class which allows reuse.

public class PersonValidator : AbstractValidator<IPerson>
{
    public PersonValidator()
    {
        Include(new IdentifierValidator());
        Include(new FirstNameValidator());
        Include(new LastNameValidator());
        Include(new BirthDateValidator());
        Include(new AddressValidator());
        Include(new EmailValidator());
    }
}

Sample property validator for FirstName property.

public class FirstNameValidator : AbstractValidator<IPerson>
{
    public FirstNameValidator()
    {
        RuleFor(person => person.FirstName)
            .NotEmpty()
            .MinimumLength(3);
    }
}

Using conventional validation works great the majority of work for validation. There are times when not all properties require validations like when adding a new record for EF Core which assigns an identifier.

Rule sets

Rules sets are setup as shown below where FirstName and LastName are a group while other properties are setup separately. This means that rules can be included or excluded for validating an object.

public class PersonValidator : AbstractValidator<Person>
{

    public PersonValidator()
    {
        RuleSet("Names", () =>
        {
            RuleFor(x => x.FirstName).NotNull();
            RuleFor(x => x.LastName).NotNull();
        });

        RuleSet("Identifier", () =>
        {
            RuleFor(x => x.PersonId).NotEqual(0);
        });

        RuleSet("Birth", () =>
        {
            RuleFor(x => x.BirthDate).BirthDateRule();
        });

        RuleSet("Email", () =>
        {
            RuleFor(x => x.EmailAddress).NotEmpty().EmailAddress();
        });
    }
}

Example to exclude the Identifier rule.

var validator = new PersonValidator();

ValidationResult result = validator.Validate(MockedData.InvalidPerson, options => options.IncludeRuleSets(
    "Names",
    "Birth"));


if (result.IsValid)
{
    Console.WriteLine("Validation succeeded.");
}
else
{
    foreach (var error in result.Errors)
    {
        AnsiConsole.MarkupLine($"{error.PropertyName,-14} [red]Error:[/] {error.ErrorMessage}");
    }
}

Example to include all rules

Using the wildcard indicates to include all rules.

Using wildcard

var validator = new PersonValidator();

// Use wildcard to include all rule sets

var result = validator.Validate(
    MockedData.InvalidPerson, options => options.IncludeRuleSets("*"));

if (result.IsValid)
{
    Console.WriteLine("Validation succeeded.");
}
else
{
    foreach (var error in result.Errors)
    {
        AnsiConsole.MarkupLine($"{error.PropertyName,-14} [red]Error:[/] {error.ErrorMessage}");
    }
}   

Source code

Provides code samples using mocked data to try out rule sets.

Console project

Summary

Rule sets open up possibilities not only for validation in applications but also for test projects.

See also

FluentValidation tips C#