Generally, fluent Validation is a validation library for .NET, and it uses lambda expressions for building validation rules for your business objects.
If you want to do simple validation in the asp.net MVC application, the data annotations validation is good, but in case if you want to implement complex validation, then you need to use Fluent Validation. Now we will learn using fluent validation in ASP.NET MVC 4 with example.
First, create a basic asp.net MVC 4 application with the name FluentValidationMVC for that Open visual studio àGo to File àSelect New àSelect Project like as shown below.
After that, you will see a new dialog for selecting your Template and Project type. From the Templates section, select Visual C# à inside that select Web and then project type select ASP.NET MVC 4 Web Application. We are giving the name “FluentValidationMVC” then finally click on the ok button.
After naming it, click on OK. After that, a new dialog will popup for selecting a template. In that, select the Basic template and click ok.
After creating the application, our project structure like as shown below.
After creating the application, let's add Fluent Validation to your project.
To add Fluent Validation to the project, right-click on your project and select Manage NuGet Packages.
After selecting a NuGet, a search dialog will popup inside NuGet dialog in search box type Fluent Validation. After searching, the first link appears of Fluent Validation created by Jeremy Skinner, as shown below.
Now click on the install button to install. After installing, it will show a green correct mark image.
After completing with installation, let’s add a Model.
For adding a model, just right click on the Model folder àselect Add àthen inside that select Class in below image you can see the process.
After clicking on the class Add New item dialog will popup with class select and asking for class name here, we will enter the class name as “Student”.
After entering the class name, click on the Add button. A Student Model is added to your project with some default code like as shown below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace FluentValidationMVC.Models
{
public class Student
{
}
}
Now let’s add properties to this Student Model.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace FluentValidationMVC.Models
{
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public DateTime StudentDOB { get; set; }
public string StudentEmailID { get; set; }
public decimal StudentFees { get; set; }
public string StudentAddress { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
}
After adding properties, we will add another class with the name StudentValidator, and this class will contain all validation rules of fluent Validation. Here we are going to add this Class to in Model folder.
After adding StudentValidator class, here is the Model folder view.
Our StudentValidator class is added to the project with some default code that will be as shown below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace FluentValidationMVC.Models
{
public class StudentValidator
{
}
}
Now we will inherit a class AbstractValidator and going to pass a parameter of Student Model to it. Here AbstractValidator is a base class for entity validator classes. Following is the code snippet after adding inherit property.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FluentValidation;
namespace FluentValidationMVC.Models
{
public class StudentValidator : AbstractValidator<Student>
{
}
}
Now going to create a Constructor inside this class add Rule in it. To write rules, we are going to use the Lambda expression of Linq.
First, we will write on the Not Empty rule. Here we wrote a rule for checking StudentName that is a Model property and it is empty or not. If StudentName is empty, then we need to send an error Message what we are given. Our code snippet will be as shown below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FluentValidation;
namespace FluentValidationMVC.Models
{
public class StudentValidator : AbstractValidator<Student>
{
public StudentValidator()
{
RuleFor(x => x.StudentName).NotEmpty().WithMessage("Student Name is required");
}
}
}
Here we wrote the NotEmpty rule for each property. Following is the code snippet with all properties rules.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FluentValidation;
namespace FluentValidationMVC.Models
{
public class StudentValidator : AbstractValidator<Student>
{
public StudentValidator()
{
RuleFor(x => x.StudentName).NotEmpty().WithMessage("Student Name is required");
RuleFor(x => x.StudentDOB).NotEmpty().WithMessage("Student DOB is required");
RuleFor(x => x.StudentEmailID).NotEmpty().WithMessage("Student EmailID is required");
RuleFor(x => x.StudentFees).NotEmpty().WithMessage("Student Fees is required");
RuleFor(x => x.StudentAddress).NotEmpty().WithMessage("Student Address is required");
RuleFor(x => x.Password).NotEmpty().WithMessage("Password is required");
RuleFor(x => x.ConfirmPassword).NotEmpty().WithMessage("Confirm Password is required");
}
}
}
In this validation, we will validate the student's age from the Birth date and give an error message if its age is less than 21. For that, we created a Boolean Method that takes DateTime as input and validates age and returns Boolean value according to it.
Following is the agevalidate method, which we created in asp.net mvc application.
private bool AgeValidate(DateTime value)
{
DateTime now = DateTime.Today;
int age = now.Year - Convert.ToDateTime(value).Year;
if (age < 21)
{
return false;
}
else
{
return true;
}
}
Here we passed that Age validates method to rule.
RuleFor(x => x.StudentDOB)
.Must(AgeValidate)
.WithMessage("Invalid date student age must be 21 or greater than 21");After validating the date, now we will validate the Email Address.
For validating an Email address, there is a built-in method called EmailAddress(). You can see below the code snippet for it.
RuleFor(x => x.StudentEmailID)
.EmailAddress()
.WithMessage("Student EmailID is required");
Validation will fail if the value of the property is outside of the specified range. The range is inclusive.
RuleFor(x => x.StudentFees)
.InclusiveBetween(0, 5000)
.WithMessage("Student Fees is not Valid");
Validation will fail if the length of the string is outside of the specified range. The range is inclusive.
RuleFor(x => x.StudentAddress)
.Length(20, 250)
.WithMessage("Address must be between 20 to 250 words");
Validation will fail if the lambda's value is not equal to the value of the property.
RuleFor(x => x.ConfirmPassword)
.Equal(x => x.Password)
.WithMessage("Password do not Match");
After completion of adding rules, here is a complete view of StudentValidator.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FluentValidation;
namespace FluentValidationMVC.Models
{
public class StudentValidator : AbstractValidator<Student>
{
public StudentValidator()
{
RuleFor(x => x.StudentName)
.NotEmpty()
.WithMessage("StudentName is required");
RuleFor(x => x.StudentDOB)
.NotEmpty()
.WithMessage("StudentDOB is required");
RuleFor(x => x.StudentDOB)
.Must(AgeValidate)
.WithMessage("Invalid date student age must be 21 or greater than 21");
RuleFor(x => x.StudentEmailID)
.NotEmpty()
.WithMessage("Student EmailID is required");
RuleFor(x => x.StudentEmailID)
.EmailAddress()
.WithMessage("Student EmailID is required");
RuleFor(x => x.StudentFees)
.NotEmpty()
.WithMessage("StudentFees is required");
RuleFor(x => x.StudentFees)
.InclusiveBetween(0,5000)
.WithMessage("Student Fees is not Valid");
RuleFor(x => x.StudentAddress)
.NotEmpty()
.WithMessage("StudentAddress is required");
RuleFor(x => x.StudentAddress)
.Length(20, 250)
.WithMessage("Address must be between 20 to 250 words");
RuleFor(x => x.Password)
.NotEmpty()
.WithMessage("Password is required");
RuleFor(x => x.ConfirmPassword)
.NotEmpty()
.WithMessage("ConfirmPassword is required");
RuleFor(x => x.ConfirmPassword)
.Equal(x => x.Password)
.WithMessage("Password do not Match");
}
private bool AgeValidate(DateTime value)
{
DateTime now = DateTime.Today;
int age = now.Year - Convert.ToDateTime(value).Year;
if (age < 21)
{
return false;
}
else
{
return true;
}
}
}
}
To add controller, right-click on the Controller folder, select Add and then select Controller.
After clicking on Controller, a new dialog will popup with the name Add Controller give name as Default1Controller and In Template select “Empty MVC controller” and finally click on the Add button that will be like as shown below.
Here is our Default1Controller code, and we made some manual configuration by adding Action Selector [HttpGet], [HttpPost] with a New Action Method Index with the Student model parameter as input.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FluentValidation.Results;
using FluentValidationMVC.Models;
namespace FluentValidationMVC.Controllers
{
public class Default1Controller : Controller
{
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Student objStudent)
{
return View(objStudent);
}
}
}
After adding the Controller, we need to access StudentValidator class. After access, we will create an object of StudentValidator class, and then we will pass the object to Fluent Validation (validator.Validate method). Now we will store that values in (ValidationResult result) and check validation using IsValid property.
if (result.IsValid)
{
}
If it is valid, it goes inside the if block, otherwise it will execute the else block. In else block, we are going to use the Foreach Loop to show the errors.
foreach (ValidationFailure failer in result.Errors)
{
ModelState.AddModelError(failer.PropertyName, failer.ErrorMessage);
}
Finally, here is the complete Index method.
[HttpPost]
public ActionResult Index(Student objStudent)
{
StudentValidator validator = new StudentValidator();
ValidationResult result = validator.Validate(objStudent);
if (result.IsValid)
{
}
else
{
foreach (ValidationFailure failer in result.Errors)
{
ModelState.AddModelError(failer.PropertyName, failer.ErrorMessage);
}
}
return View(objStudent);
}
To add View, right-click inside Index ActionResult Method and Select "Add View" to create the view template for our Index form. Here in the below snapshot, we selected View engine as Razor, and we are going to create a strong type of view for that I have selected Model class Student. We want to create an input form for that I have selected Create in Scaffold template. Finally, click on the Add button.
After adding the view, the following complete code of Index.cshtml view that is generated.
@model FluentValidationMVC.Models.Student
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Student</legend>
<div class="editor-label">
@Html.LabelFor(model => model.StudentName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.StudentName)
@Html.ValidationMessageFor(model => model.StudentName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StudentDOB)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.StudentDOB)
@Html.ValidationMessageFor(model => model.StudentDOB)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StudentEmailID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.StudentEmailID)
@Html.ValidationMessageFor(model => model.StudentEmailID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StudentFees)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.StudentFees)
@Html.ValidationMessageFor(model => model.StudentFees)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StudentAddress)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.StudentAddress)
@Html.ValidationMessageFor(model => model.StudentAddress)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ConfirmPassword)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ConfirmPassword)
@Html.ValidationMessageFor(model => model.ConfirmPassword)
</div>
<p>
<input type="submit" value="Create"/>
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Now just run the application and entering URL http://localhost:####/ Default1/index to access the page. Here is the output of the fluent validation asp.net application before entering validate data.
Here is the output of the fluent validation asp.net application after entering invalid data.
Here is the output of the fluent validation asp.net application after entering valid data.
This is how we can use fluent validation in asp.net mvc to implement custom validations in applications.