In this article, we will explore how to validate Asp.net MVC Application Using Fluent Validation.
If you want to do simple validation in our asp.net MVC application then Data Annotation is good but when it comes to applying complex validation to manage it with Data Annotation is a little bit difficult.
For complex validation, it is good to use FLuent Validation.
Introduction to Fluent Validation
Fluent Validation is a small validation library of .net that uses lambda expressions for creating validation rules for your business models.
Implementing Fluent Validation in your ASP.net MVC Application
First Create a basic asp.net MVC Application named as MVCFluentValidationDemo.
Add Fluent Validation in Application
To add fluent validation in your MVC application right-click on your project and select the manage NuGet package option as shown below.
Now in the dialog search for Fluent Validation select the first link shown in the image and click on install.
Add Model in your Application name it as Employee. cs and add the below properties in it.
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MVCFluentValidationDemo.Models { public class Employee { public string FirstName { get; set; } public string LastName { get; set; } public string CompanyName { get; set; } public DateTime DOB { get; set; } public string Email { get; set; } public int Salary { get; set; } } }
Now add one more Class and name it as EmployeeValidator.cs. In this class, we will be declaring all the validation rules of fluent validation for the Employee class. In this example, we are creating this validator class also in the model folder.
After Creating the Validator class, we will inherit AbstractValidator class and will pass the parameter of the Employee Model. AbstractValidator class is a base class for fluent Validation.
using FluentValidation; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MVCFluentValidationDemo.Models { public class EmployeeValidator : AbstractValidator<Employee> { } }
Adding Rule in Validator Class
we will create a construct in the validator class and write the rules in it. Here First we will write the Not Empty rule for each property of the Employee model. If any property is blank then a validation message will be thrown that we are given for the corresponding property.
using FluentValidation; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MVCFluentValidationDemo.Models { public class EmployeeValidator : AbstractValidator<Employee> { public EmployeeValidator() { RuleFor(x => x.FirstName).NotEmpty().WithMessage("First Name is Required"); RuleFor(x => x.LastName).NotEmpty().WithMessage("Last Name is Required"); RuleFor(x => x.CompanyName).NotEmpty().WithMessage("Company Name is Required"); RuleFor(x => x.DOB).NotEmpty().WithMessage("Date of Birth is Required"); RuleFor(x => x.Email).NotEmpty().WithMessage("Email is Required"); RuleFor(x => x.Salary).NotEmpty().WithMessage("Salary is Required"); } } }
Now let us see some more Validation of Fluent.
Validating Date (Age)
In this, we will validate that employee age should be greater than 18. we will compare the DOB property with the current year. For this, we will create a boolean function that will perform the action.
private bool ValidateAge(DateTime age) { DateTime dateTime = DateTime.Today; int actualAge = dateTime.Year - Convert.ToDateTime(age).Year; if (actualAge < 18) { return false; } return true; }
The rule for DOB is as follow:-
RuleFor(x => x.DOB).Must(ValidateAge).WithMessage("Employee age must be 18 or greater than 18");
Here must return true if the function returns true else it will throw the error message.
Validating Email
To validate email address fluent validation is having built-in method EmailAddress(). That will validate the email address.
RuleFor(x => x.Email).EmailAddress().WithMessage("Email is not valid");
Validating String Length (Company Name)
To validate String length, fluent validation is having the built-in method Length(). we will give the min and max length required for the string .and Fluent Validation will throw an error if the string falls out of the given range.
RuleFor(x => x.CompanyName).Length(5, 500).WithMessage("Company Name must be between 0 to 500 character");
Validating int should be greater than a given value(Salary)
Here we will check whether the salary is greater than the given value or not. we will use GreatherThan() built-in function for Fluent Validation for this.
RuleFor(x => x.Salary).GreaterThan(1000).WithMessage("Employee Salary should be greater than 1000");
Complete code of EmployeeValidator.cs Class is as below
using FluentValidation; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MVCFluentValidationDemo.Models { public class EmployeeValidator : AbstractValidator<Employee> { public EmployeeValidator() { RuleFor(x => x.FirstName).NotEmpty().WithMessage("First Name is Required"); RuleFor(x => x.LastName).NotEmpty().WithMessage("Last Name is Required"); RuleFor(x => x.CompanyName).NotEmpty().WithMessage("Company Name is Required"); RuleFor(x => x.DOB).NotEmpty().WithMessage("Date of Birth is Required"); RuleFor(x => x.Email).NotEmpty().WithMessage("Email is Required"); RuleFor(x => x.Salary).NotEmpty().WithMessage("Salary is Required"); RuleFor(x => x.CompanyName).Length(5, 500).WithMessage("Company Name must be between 0 to 500 character"); RuleFor(x => x.DOB).Must(ValidateAge).WithMessage("Employee age must be 18 or greater than 18"); RuleFor(x => x.Email).EmailAddress().WithMessage("Email is not valid"); RuleFor(x => x.Salary).GreaterThan(1000).WithMessage("Employee Salary should be greater than 1000"); } private bool ValidateAge(DateTime age) { DateTime dateTime = DateTime.Today; int actualAge = dateTime.Year - Convert.ToDateTime(age).Year; if (actualAge < 18) { return false; } return true; } } }
Now to Test Fluent Validation Create an EmployeeController in the Controller folder and place the below code in it.
public class EmployeeController : Controller { [HttpGet] public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(Employee employee) { EmployeeValidator validationRules = new EmployeeValidator(); ValidationResult result = validationRules.Validate(employee); if (!result.IsValid) { foreach (var item in result.Errors) { ModelState.AddModelError(item.PropertyName, item.ErrorMessage); } } return View(employee); } }
now right-click on Index() -> Add View and create a view with Create Template for Employee Model. It will create an Index.cshtml inside Employee Folder in Views
Index.cshtml file will look like this
@model MVCFluentValidationDemo.Models.Employee @{ ViewBag.Title = "Index"; } @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Employee</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.CompanyName, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.CompanyName, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.CompanyName, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.DOB, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.DOB, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.DOB, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Salary, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Salary, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Salary, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" class="btn btn-default" /> </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
Now run the application and place this URL to see access the page:- https://localhost:#####/Employee/Index
you will see the below page before entering validated data in the form.
Now here is the final result after adding invalid data with the fluent validation error message.
Now After Adding Valid Data the final out is shown below: –
This is how we can use fluent validation in asp.net MVC. The Source Code of the project is Here.
To learn how we can implement fluent validation in Asp.net Core WebApi Project Please refer to the Link
Thanks for Reading.Hope this article helps you