Quick Overview:
The FluentValidation simplifies the creation of custom validation rules and allows you to handle complex validation with ease. However, as efficient as it is, prompting it with the right configuration is equally important, therefore, in this blog post, we will first recall our understanding of FluentValidation and then look into the steps to configure FluentValidation in ASP Dot NET Core along with that we will also take a glimpse of the features and benefits of FluentValidation that makes it so crucial for the success and efficiency of your business application.

What is FluentValidation?

Fluent Validation .NET Core Web API is a renowned .NET library that creates strong, maintainable validation rules for objects in a type-safe manner. It helps your development teams define the validation rules in a fluent, intuitive way which helps make your code more readable and maintainable. The FlutentValidation supports platforms such as .NET Standard 2.0, .NET Core 3.1, .NET 5, .NET 6, and .NET 7.)

Features and Benefits of FluentValidation .NET Core API

As with every library framework or tech stack within the market, ASP .NET Core Web API Fluent Validation also has its own set of benefits and features that make it stand out. Here is a list of a few:

  • Inbuilt Validators: It has several validators such as Regular Expression, Email, Credit Card, and more.
  • Localization: It helps provide translations for the default validation messages within several messages.
  • Custom Validators: There are several ways by which you can create a custom, reusable validator.
  • Asynchronous Validation: It refers to giving you the ability to define the asynchronous rules such as when working with an external API.
  • Test Extensions: It offers a few extensions that can help with the testing of your validator classes.
  • Transforming Values: With this you can apply a transformation to a property value before the validation is performed against it.

Configuring FluentValidation in ASP.NET Core

For configuring the FluentValidation in ASP.NET Core, here are the steps that you should follow:

Step 1: Installing NuGet

Install the NuGet packages to use the FluentValidation.

Install-Package FluentValidation.AspNetCore
Install-Package FluentValidation.DependencyInjectionExtensions

Step 2: Configuration Process

The next step is the Fluent Validation .NET Core Web API configuration for which initially you must do the automatic registration of validators which is crucial. You can also make use of the FluentValidation.DependencyInjectionExtensions package, this here you can use to automatically find all the validators within a precise assembly using an extension method.

using FluentValidationDemoApp.Data;
using FluentValidation.AspNetCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System.Configuration;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

// Now you should add the services to the container.
builder.Services.AddControllers();

builder.Services.AddDbContext<ApplicationDBContext>(options =>
{
    options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection"));
});

builder.Services.AddControllers()
            .AddFluentValidation(v =>
            {
                v.ImplicitlyValidateChildProperties = true;
                v.ImplicitlyValidateRootCollectionElements = true;
                v.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly());
            });

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Now configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

The above-given code will add the FluentValidation pipeline for the Controllers.

Step 3: Validator Implementation

For defining the set of validation rules for the specific object, you should create a class that will be responsible for inherits from the AbstractValidator<T>, where T is the type of the class that you plan on validating. 

The validation rules themselves need to be defined within the validator class constructor. To specify the validation rules for a specific property you must call the RuleFor method which will pass a lambda expression indicating the property that you want to validate.

using FluentValidationDemoApp.DTOs;
using FluentValidation;

namespace FluentValidationDemoApp.Validations
{
    public class CustomerValidator : AbstractValidator<CustomerDTO>
    {
        public CustomerValidator()
        {
            RuleFor(x => x.Name).NotNull().NotEmpty();
            RuleFor(x => x.Name).Length(20, 250);
            RuleFor(x => x.PhoneNumber).NotEmpty().WithMessage("Please specify a phone number.");
            RuleFor(x => x.Age).InclusiveBetween(18, 60);

            // These are the Complex Properties
            RuleFor(x => x.Address).InjectValidator();

            // Moving ahead with the Other way
            //RuleFor(x => x.Address).SetValidator(new AddressValidator());

            // This is for the Collections of Complex Types
            //RuleForEach(x => x.Addresses).SetValidator(new AddressValidator());
        }
    }
}
using FluentValidationDemoApp.DTOs;
using FluentValidation;

namespace FluentValidationDemoApp.Validations
{
    public class AddressValidator : AbstractValidator<AddressDTO>
    {
        public AddressValidator()
        {
            RuleFor(x => x.State)
                .NotNull()
                .NotEmpty();

            RuleFor(x => x.Country)
                .NotEmpty()
                .WithMessage("Please specify a Country.");

            RuleFor(x => x.Postcode)
                .NotNull()
                .Must(BeAValidPostcode)
                .WithMessage("Please specify a valid postcode");
        }

        private bool BeAValidPostcode(string postcode)
        {
            return postcode.Length == 6;
        }
    }
}

Explaining the Code

  • Here we are using the RuleForEach method for applying the same rule for multiple items within a collection. Also, we can combine the RuleForEach with the SetValidator when the collection is of another complex object. 
  • The RuleSets enables you to group validation rules which can further be executed together as a group while ignoring the other rules.
  • The Including Rules implies that you can include the rules from other validators delivering on the condition they validate the same type. This enables splitting rules across classes and composes them together.
  • Validators are also allowed to be used with any dependency injection library. For injecting a validator for a specific model, you should register the validator with the service provider as an IValidator<T>. services.AddScoped<IValidator<Customer, CustomerValidator>();
namespace FluentValidationDemoApp.Entities
{
    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public int Age { get; set; }
        public string PhoneNumber { get; set; } = string.Empty;
        public bool IsAdult { get; set; }
        public Address? Address { get; set; }
    }
}
namespace FluentValidationDemoApp.Entities
{
    public class Address
    {
        public int Id { get; set; }
        public string Line1 { get; set; } = string.Empty;
        public string Line2 { get; set; } = string.Empty;
        public string Town { get; set; } = string.Empty;
        public string Postcode { get; set; } = string.Empty;
        public string Country { get; set; } = string.Empty;
        public string State { get; set; } = string.Empty;
    }
}

You are not required to explicitly check the ModelState within the controllers to observe if the input is valid. Within the FluentValidation the ASP.NET middleware is responsible for automatically finding our validator, and for the cases where the validation fails, it will prepare the ModelState which will lead our action to return a response 400.

using FluentValidationDemoApp.Data;
using FluentValidationDemoApp.DTOs;
using FluentValidationDemoApp.Validations;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace FluentValidationDemoApp.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CustomerController : ControllerBase
    {
        private readonly ApplicationDBContext _applicationDBContext;

        public CustomerController(ApplicationDBContext applicationDBContext)
        {
            _applicationDBContext = applicationDBContext;
        }

        [HttpPost("AddNewCustomer", Order = 0)]
        public IActionResult Add(CustomerDTO customer)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            _applicationDBContext.Add(customer);
            _applicationDBContext.SaveChanges();

            return Ok();
        }

        [HttpPost("UpdateNewCustomer", Order = 1)]
        public IActionResult Update(CustomerDTO customer)
        {
            CustomerValidator validator = new CustomerValidator();
            var validationResult = validator.Validate(customer);

            if (!validationResult.IsValid)
            {
                return BadRequest(validationResult.Errors);
            }

            _applicationDBContext.Update(customer);
            _applicationDBContext.SaveChanges();

            return Ok();
        }
    }
}

Within the ASP .NET Core Web API Fluent Validation, here you can also explicitly validate the models anywhere. The Validate method here returns a ValidationResult object which contains two properties. One is “IsValid” which is a boolean that mentions whether the validation succeeded or not. The “Errors” is a collection of ValidationFailure objects which contain details about any kind of validation failure.

Looking to Effortlessly Boost Your .NET Project?

Equip your team with exceptional .NET expertise. Bring our skilled .NET Developer on board for your projects now!

Conclusion

In conclusion, we are sure that this blog post must have given you significant insight into the ideal steps to configure Fluent Validation .NET Core Web API. However, as a business owner, for more information you can refer to our blog post, FluentValidation in .NET Core: A Complete Guide or if you feel stuck within the process you can refer to our detailed blog or are occupied focusing on your core business operations then, get in touch with a leading ASP.NET Core application development company like Positiwise to help you with ASP .NET Core Web API Fluent Validation process and pace up your development process.

Parag Mehta

Verified Expert in Software & Web App Engineering

Parag Mehta, the CEO and Founder of Positiwise Software Pvt Ltd has extensive knowledge of the development niche. He is implementing custom strategies to craft highly-appealing and robust applications for its clients and supporting employees to grow and ace the tasks. He is a consistent learner and always provides the best-in-quality solutions, accelerating productivity.

Related Posts