Fluent Validation
Hello everyone, we will be talking about validations with Fluent Validation library on this Article.
Fluent Validation is a Library that help us with validation Rules like:
→The password can not be empty,
→Name can not be less than two and more than 20 words.
→The password should contain one upper case and at least 8 character.
→Password confirmation does not match with password field.
→ Card number can not be empty.
These are validation errors that’s how the application let us to know what should we change and what conditions are required to complete operations like registration, payment or to save a data.
In ASP.NET we can add our validations in our model class or in DTO class with using “System.ComponentModel.DataAnnotations” as in the below code.
using System.ComponentModel.DataAnnotations;
namespace ECommerce.Dto
{
public class RegisterDto
{
[Required]
[DataType(DataType.EmailAddress)]
[RegularExpression(@"^[a-zA-Z0-9._%+-]+@gmail\.com$", ErrorMessage = "Geçersiz Email adresi")]
public string Email { get; set; }
[StringLength(20, MinimumLength = 3)]
public string FirstName { get; set; }
[StringLength(15, MinimumLength = 2)]
public string LastName { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Compare("Password")]
public string ConfirmPassword { get; set; }
}
}
As you see in the code that’s how we can add our validations but it does not seems so clear, right? And what if we use the same class more than one time? will we write the same validations code again and again?
When we developed a small project that may not be a real problem for us. But when there is a huge projects, that can create a cause to understand and make changes on the code. That’s why using Fluent Validation and making valiadtion operations in another folder will make the project maintainable and clear.
Let’s make and example to understand how we can use it.
Firs to be able to use FluentValidation we need to install the package from NuGet Packages
Now we can start to write the code, Let’s go.
I have created a user class it will be and we will add some validations rules for it.
namespace FluentValdation.Entities
{
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public DateTime BirthDate { get; set; }
}
}
I have created a UserValidator class and its implementing AbstractValidator.
using FluentValdation.Entities;
using FluentValidation;
namespace FluentValdation.FluentValdiation
{
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(u => u.Email).NotEmpty().WithMessage("Your valdiation message here");
RuleFor(u => u.Email).EmailAddress();
RuleFor(u => u.LastName).MaximumLength(12);
RuleFor(u => u.LastName).NotEmpty();
RuleFor(u => u.FirstName).NotEmpty().MinimumLength(2).MaximumLength(20);
RuleFor(u => u.BirthDate).NotEmpty();
}
}
}
Abstract validator class coming from FluentValidation library. And if you have any other class which you wanto to add valdaitons you can do the same just create your class and create it’s validator class. I suggest you to hold validator in a different folder to make it less complex.
As you can check in the code I have added some methods like NotEmpty, EmailAddress, MinumumLength and MaximumLength. But there are more methods in FluentValidation even you can create your own validation method too. Thats why I suggest you to check Fluent validation documents from here to learn more about it this blog is only a demo :)
We have created our class and validation rules now we have to deal with program.cs configuration which is quite easy.
This code is let your progrom to know about your class will be working with Fluent validation.
I have created a controller complete and show you that how we can activate our valdation rules.
using FluentValdation.Entities;
using FluentValidation;
using FluentValidation.Results;
using Microsoft.AspNetCore.Mvc;
namespace FluentValdation.Controllers
{
[ApiController]
[Route("api/[Controller]")]
public class UserController: ControllerBase
{
private readonly IValidator<User> _validator;
public UserController(IValidator<User> validator)
{
_validator = validator;
}
[HttpPost]
public async Task<IActionResult> CreateUser(User user)
{
ValidationResult result = await _validator.ValidateAsync(user);
if (!result.IsValid)
{
return Ok(result.ToDictionary());
}
return Ok(result);
}
}
}
As you see in the code we are injecting IValidator interface with generic type and in the post method we are calling ValidateAsync method and it’s checkin if there is any validation error its returning the error. if there is not its going on the operation.
I have created ASP.NET Web API project version of .NET 6 that’s why Swagger configuration is coming defaultly I suggest you to the same because it will take less time to test our CreateUser endpoint. If you want you can use Postman too.
Let’s test it and see how its working.
I sened a request for our user class but I didnt send the object correctly.
Lets see The result:
As you see it gaves some errors, thanks to Fluent :) Errors coming in turkish language because of the browser language is turkish it will be in your browser language.
That’s not a perfect example it’s was just a demo to show you how you can configure it to your project and understand the reason why do we use Flunet Validation.
I suggest you to look for Aspect Oriented Programing(AOP). A better configuration would be with using AOP approach.
You can check the code from here.
I am learning a lot while I am writing I hope you learned a lot too while you are reading and enjoyed it. Don’t forget to follow on Medium to keep learning together. See you soon :)