C# Academy · Lesson

FluentValidation Rules

Write expressive validators with fluent syntax.

Lesson 2 of 413 steps

FluentValidation Rules is a free C# Academy lesson on CoddyKit. This is lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, and your progress syncs across the web and the CoddyKit app. The C# Academy course includes 4 lessons in total.

Why FluentValidation?

FluentValidation is a popular .NET library that moves validation rules out of your models and into dedicated validator classes. Rules are expressed with a readable, chainable (fluent) API, keeping models clean and rules testable.

dotnet add package FluentValidation
dotnet add package FluentValidation.DependencyInjectionExtensions

The AbstractValidator Base Class

You write a validator by inheriting from AbstractValidator<T>, where T is the model you validate. Rules are defined in the constructor.

using FluentValidation;

public class CustomerValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {
        // rules go here
    }
}

Defining Your First Rule With RuleFor

RuleFor selects a property via a lambda, then you chain validators onto it. NotEmpty() rejects null, empty strings and default values.

public class CustomerValidator : AbstractValidator<Customer>
{
    public CustomerValidator()
    {
        RuleFor(c => c.Name).NotEmpty();
    }
}

Chaining Multiple Validators

Each RuleFor can chain several validators. They run in order and all must pass. This reads almost like a sentence.

RuleFor(c => c.Name)
    .NotEmpty()
    .MinimumLength(2)
    .MaximumLength(50);

Built-In Validators

FluentValidation ships with many validators: NotNull, NotEmpty, EmailAddress, Length, InclusiveBetween, GreaterThan, Matches (regex) and more.

RuleFor(c => c.Email).NotEmpty().EmailAddress();
RuleFor(c => c.Age).InclusiveBetween(18, 120);
RuleFor(c => c.Phone).Matches(@"^\+?[0-9]{7,15}$");

Custom Error Messages

Use WithMessage to override the default message. You can interpolate placeholders like {PropertyName} and {PropertyValue}.

RuleFor(c => c.Email)
    .NotEmpty().WithMessage("Email is required.")
    .EmailAddress().WithMessage("{PropertyValue} is not a valid email.");

Custom Error Codes And Severity

Beyond messages you can attach a machine-readable WithErrorCode and a WithSeverity (Error, Warning, Info) to help clients react differently.

RuleFor(c => c.Name)
    .NotEmpty()
    .WithErrorCode("NAME_REQUIRED")
    .WithSeverity(Severity.Error);

Validating Nested Objects

Use SetValidator to reuse a validator for a child object, keeping rules modular.

public class OrderValidator : AbstractValidator<Order>
{
    public OrderValidator()
    {
        RuleFor(o => o.Customer).SetValidator(new CustomerValidator());
    }
}

Validating Collections

RuleForEach applies rules to every item in a collection.

public class OrderValidator : AbstractValidator<Order>
{
    public OrderValidator()
    {
        RuleForEach(o => o.Items)
            .ChildRules(item => item.RuleFor(i => i.Quantity).GreaterThan(0));
    }
}

Running A Validator Manually

You can invoke a validator directly and inspect the result. ValidationResult exposes IsValid and an Errors list.

var validator = new CustomerValidator();
ValidationResult result = validator.Validate(customer);

if (!result.IsValid)
{
    foreach (var error in result.Errors)
    {
        Console.WriteLine(error.PropertyName + ": " + error.ErrorMessage);
    }
}

Async Validation

When a rule needs I/O (like a database check), use ValidateAsync and async validators such as MustAsync, which we explore in the custom rules lesson.

ValidationResult result = await validator.ValidateAsync(customer);

Quick Check

Test your FluentValidation basics.

Recap

FluentValidation puts rules in AbstractValidator<T> classes. RuleFor targets a property, then you chain built-in validators like NotEmpty, EmailAddress and InclusiveBetween. Customize feedback with WithMessage, WithErrorCode and WithSeverity, reuse logic with SetValidator and RuleForEach, and run rules via Validate/ValidateAsync.

Free to start

Learn C# with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
93
Lessons
346

Frequently Asked Questions

Is the “FluentValidation Rules” lesson free?

Yes — the full text of “FluentValidation Rules” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO. The C# Academy course includes 4 lessons in total.

What will I learn in “FluentValidation Rules”?

Write expressive validators with fluent syntax. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 2 of 4.

How long does the “FluentValidation Rules” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Data Annotation Validation
  2. FluentValidation Rules
  3. Custom and Conditional Rules
  4. Integrating Validation with APIs
← Back to C# Academy