To preserve the integrity, consistency, and security of application data, you should ensure that your application receives the correct data in a proper format. A popular open-source library in the C# ecosystem handles this perfectly and easily—FluentValidation. FluentValidation is a validation library for .NET that provides a fluent interface to build strongly typed validation rules in your applications. A fluent interface is an object-oriented API that makes it easy to chain method calls together.

In this article, I’ll introduce you to FluentValidation, explain why you should use it, and show you how to use this library in your ASP.NET applications to achieve clean, elegant, flexible, and maintainable validation logic. To use the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here.

Create an ASP.NET Core Web API project in Visual Studio 2022

To create an ASP.NET Core Web API project in Visual Studio 2022, follow the steps outlined below.

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project. Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  6. Click Next.
  7. In the “Additional Information” window shown next, select “.NET 8.0 (Long Term Support)” as the framework version and uncheck the check box that says “Use controllers,” as we’ll be using minimal APIs in this project.
  8. Elsewhere in the “Additional Information” window, leave the “Authentication Type” set to “None” (the default) and make sure the check boxes “Enable Open API Support,” “Configure for HTTPS,” and “Enable Docker” remain unchecked. We won’t be using any of those features here.
  9. Click Create.

We’ll use this ASP.NET Core Web API project to work with the code examples given in the sections below.

What is FluentValidation? Why should we use it?

FluentValidation is an open-source library for .NET that enables you to create strongly typed validation rules in your applications. FluentValidation uses a fluent interface and strives to improve code readability using method chaining and flowing expressions. You can use FluentValidation to declaratively define your own validation rules, focusing on “what” needs validating instead of “how” to validate it.

Here are four reasons why you should use FluentValidation in your .NET applications:

  1. Simplicity. FluentValidation’s syntax is intuitive, making your validation rules easy to write, understand, and maintain.
  2. Flexibility. You can use FluentValidation to define simple or complex validation rules, and to create custom validation methods.
  3. Separation of concerns. FluentValidation helps you to isolate your validation logic from your application’s business logic, thereby making the code of your application clean and maintainable.
  4. Integration. FluentValidation integrates easily with popular frameworks including ASP.NET and ASP.NET Core.

The problem with data annotations

If you’re using data annotations to enforce validation rules, you would typically decorate your classes using attributes as shown below.

public class Author
{
    [Required(ErrorMessage = "FirstName is required.")]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }
    [Required(ErrorMessage = "LastName is required.")]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }
    [Required(ErrorMessage = "Email is required.")]
    [Display(Name = "Email Address")]
    public string Email { get; set; }
    [Required(ErrorMessage = "NumberOfBooks is required.")]
    [Display(Name = "Number of Books Written")]
    public int NumberOfBooks { get; set; }
}

The downside of this approach is that your business object now contains validation rules as well. In other words, when you’re using data annotations, the validation rules will be tightly coupled with your model classes. As a result, using data annotations violates the separation of concerns principle because the validation logic is tied to your domain logic.

FluentValidation allows you to easily separate these concerns.

Install the FluentValidation NuGet package

To work with FluentValidation library, we’ll need to install the FluentValidation NuGet package in our project. To do this, select the project in the Solution Explorer window, then right-click and select “Manage NuGet Packages.” In the NuGet Package Manager window, search for the FluentValidation package and install it.

Alternatively, you can install the package via the NuGet Package Manager console by entering the command shown below.

PM> Install-Package FluentValidation

Create a validator class in ASP.NET Core

You can validate data pertaining to an instance of the Author class we examined above in a much cleaner way using FluentValidation. Since we’ll be using FluentValidation, let us remove all of the attributes we applied on each of the properties of the Author class. The updated Author class now looks like this:

public class Author
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public int NumberOfBooks { get; set; }
}

Create a new class named AuthorValidator that extends the AbstractValidator abstract class as shown in the code snippet given below.

public class AuthorValidator : AbstractValidator
{
    public AuthorValidator()
   {
       RuleFor(x => x.FirstName).NotNull().
       WithMessage("Author first name cannot be null or empty");
       RuleFor(x => x.LastName).NotNull().
       WithMessage("Author last name cannot be null or empty");
       RuleFor(x => x.Email).NotNull().EmailAddress();
       RuleFor(author =>
       author.NumberOfBooks).NotEmpty().GreaterThan(0). 
       WithMessage("An author should have written at least one book");
    }
}

The FluentValidation library provides several built-in validators. Note that we’ve used four of them in the AuthorValidator class above.

Create a validation endpoint in ASP.NET Core

To validate input data, you can create a HTTP Post endpoint named /validateauthor as shown in the code snippet given below.

app.MapPost("/validateauthor", async (Author request, IValidator validator) =>
{
    var validationResult = await validator.ValidateAsync(request);
    if (!validationResult.IsValid)
    {
        return Results.ValidationProblem(validationResult.ToDictionary());
    }
    return Results.Accepted();
});

Register the validation class in ASP.NET Core

Lastly, you should register the AuthorValidator in the Program.cs file using the following code snippet.

builder.Services.AddScoped, AuthorValidator>();

Execute the application

Finally, run the application and browse the /validateauthor endpoint. Launch Postman and invoke the /validateauthor endpoint by passing Author data in JSON format in the request body as shown in Figure 1.

FluentValidation ASPNET Core

Figure 1. FluentValidation in action.

IDG

You can see the output in the response body as shown in Figure 1. Because the NumberOfBooks property of the Author class has been configured to be not empty and greater than or equal to 1, the validation endpoint returns an error. You can see the error message in the response.

FluentValidation is a good choice when you need to implement complex custom validation rules in the domain models or data transfer objects in your application. In this article, we’ve used the built-in validators of the FluentValidation library. I’ll take a look at custom validators, chaining validators, and other features of FluentValidation in a future post here.