In this article, we will explore how to validate Asp.net Core Api Using Fluent Validation.
When it comes to validating the Model we all learning toward Data Annotation aren’t We?. But there are lots of scenario issues with this scalable System.
To Overcome this issue there is a library (Fluent Validation) in Ap.net which makes validation models Easy And Clean.
Fluent Validation is a .Net Validation Library that helps to create clean and easy validation for your API. It helps you to separate Model Classes with the validation.
Note :- Fluent Validatiion Uses Lambda Expression for buildin validation.And Its Supports Integration with ASP.NET Core 3.1 and higher versions and also with ASP .NET MVC.
Create a basic .net Core Project and create a new folder in the solution Name as Validators. In which We will Add all our validation classes.YOur basic project struct will look like this:-
To use Fluent Validation in your ASP .Net Core app you need to install it. Install fluent validation package by writing the following command in your package manager console.
Install-Package FluentValidation.AspNetCore.
After Successful installation now configure Fluent Validation in your project. For configuration we need to add fluent validation in our project Startup.cs file under ConfigureServices() Function.
add the following line in your ConfigurationService()
services.AddMvc(setup => { //...mvc setup... }).AddFluentValidation();
and import a Fluent validation package.
using FluentValidation.AspNetCore;
After Successful configuration, Now Create a model class which we will be validated using fluent validation.
Here I m Creating an Employee.cs Model With some basic properties.
public class Employee { public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public int Age { get; set; } public int Salary { get; set; } }
Now Create an EmployeeController in Controller Folder and create a POST function Create in it.
public class EmployeeController : ControllerBase { [HttpPost] public async Task<IActionResult> Create (Employee input) { return Ok(); } }
To apply validation to our Model/Class Property we have to build Custom Validator. These Validators are Abstract validators of type T where T can be any of your model /class which you want to validate.
After Creating Controller let us now create our first validator class to validate Employee.cs Model Class.
Create EmployeeValidator.cs class in your validator folder whose base class is AbstractValidator of type T, Here T is our Employee.cs Model. And create a constructor to define rules for validation
public class EmployeeValidator : AbstractValidator<Employee> { public EmployeeValidator() { RuleFor(p => p.FirstName).NotEmpty(); } }
After creating a validator now register your service for asp.net to discover your validators in a startup.cs by calling the AddTransient method for each validator as below.
services.AddTransient<IValidator<Employee>, EmployeeValidator>();
Now, let’s run your app to test. Here I’m using Postman and sending a post request by filling in all the records.
{ "firstName": "Ankita", "lastName": "jain", "email": "aj@gmail.com", "dob": "1998-11-13T09:32:20.185Z", "salary": 10000 }
Everything work fine we get Ok Response:-
Now to test the validator make FirstName an empty string and again send a post request and see the result you will get 400 Bad Result and error messages.
Now, this is how basic fluent validators work let us see how we can add a Custom message for validation and different type of validations.
modify the existing rule as given below:-
RuleFor(p => p.FirstName).NotEmpty().WithMessage("{PropertyName} should be not empty. NEVER!");
use PropertyName to get the corresponding property names these are the place holder of the fluent validation library.
now again run your project and pass FirstName as blank and see the result.
This is how you can add custom messages to your validation.
Now let us see Different validation.
String Length validation:-
let say our FirstName must have a length between 4 to 50 characters long. Then modify the rule as below and run the API again and pass FirstName as empty.
RuleFor(p => p.FirstName).NotEmpty().WithMessage("{PropertyName} should be not empty. NEVER!").Length(4,50);
you will get the following result:-
Getting two validation for the single field is not practically good validator should story on first validation for a specific property,to achieve this modify the rule as below:-
RuleFor(p => p.FirstName).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty().WithMessage("{PropertyName} should be not empty. NEVER!").Length(4,50);
Here Cascade(CascadeMode.StopOnFirstFailure) will stop the validator when it gets the first error for a specific property and prevents the validator to throw multiple validations for a single property.
Now run your API again and pass FirstName as an empty string you will see it will give you a validation message for required.
Now add 3 characters in FirstName
{ "firstName": "ank", "lastName": "jain", "email": "aj@gmail.com", "dob": "1998-11-13T09:32:20.185Z", "salary": 10000 }
and see it will give you validation for length.
Let’s say we can pass number in our firstname and as per API it is ok but practically it is incorrect, firstname should be in letters only.For this let’s create a helper method that returns true and false based on its content.
we will create a helper method in our validator itself as below.
private bool IsValidName(string name) { return name.All(Char.IsLetter); }
now add the custom method in our rule as below and modify the existing rule.
RuleFor(p => p.FirstName).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty().WithMessage("{PropertyName} should be not empty ").Length(4, 50).Must(IsValidName).WithMessage("{PropertyName} should be all letters.");
and run your API and pass “1234” in firstname and see the result you will get the following result.
this is how we can add custom methods in our Validation
Now let us see different validation.
Now let us add different validation rules for all the properties of Employee.cs Model
your final EmployeeValidator.cs will look as follow.
public EmployeeValidator() { RuleFor(p => p.FirstName).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty().WithMessage("{PropertyName} should be not empty.").Length(4, 50) .Must(IsValidName).WithMessage("{PropertyName} should be all letters."); RuleFor(p => p.LastName).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty().WithMessage("{PropertyName} should be not empty.").Length(4, 50) .Must(IsValidName).WithMessage("{PropertyName} should be all letters."); RuleFor(p => p.Email).EmailAddress().WithMessage("{PropertyName} is not a valid Email!"); RuleFor(x => x.DOB).Must(Validate_Age).WithMessage("Age should be grater than 18"); RuleFor(x => x.Salary).GreaterThanOrEqualTo(1000).LessThanOrEqualTo(50000); } private bool IsValidName(string name) { return name.All(Char.IsLetter); } private bool Validate_Age(DateTime Age_) { DateTime Current = DateTime.Today; int age = Current.Year - Convert.ToDateTime(Age_).Year; if (age < 18) { return false; } else { return true; } }
Here we have added validation for LastName, Email, Age greater than 18, and salary must be between 1000-50000
There are some Built-in validators in available in fluent validation. Check Out Here .
If you want full source code and how it works you can view my GitHub repository by clicking the GitHub Link.
In this article, we have to show Create and Used PIPE in angular
In this article, we have to show Create and Used PIPE in angular
In this article, we have to show Create and Used PIPE in angular