ASP.Net MVC Validation Using Fluent Validation

This article explains how to implement ASP.NET MVC validation using Fluent Validation. Fluent validation is a small validation library for .NET that uses a Fluent interface and lambda expressions for building validation rules for your business objects.  Fluent validation is one way of setting up dedicated validator objects, that you would use when you want to treat validation logic as separate from business logic. The Aspect-Oriented Programming (AOP) paradigm enables separation of cross-cutting concerns within a system, and validation is one such concern. Separating validation helps clean up your domain code and make it more cohesive, as well as giving you a single place to look for validation logic.

I have explained other techniques in my previous two articles. These are:

ASP.NET MVC Server-Side Validation
ASP.NET MVC Client-Side Validation

I create a Customer model (Customer class under Models folder) that has two properties, one is "Email" and another is "Name" as in the following code snippet:

  1. namespace MvcValidation.Models  
  2. {  
  3.     public class Customer  
  4.     {  
  5.         public string Name { getset; }  
  6.         public string Email { getset; }  
  7.     }  
  8. }

Now I install the Fluent validation Nuget package in the application so I can use Fluent validation rules.

MVC-1.jpg

Figure 1.1 Install FluentValidation NuGet package

After that I create a validator class for the Customer model under the "Validators" folder but you can create it anywhere in an application for validation rules on Customer properties. I used two rules, one is not empty and another validates an email address.

  1. using FluentValidation;  
  2. using MvcValidation.Models;  
  3. namespace MvcValidation.Validators  
  4. {  
  5.     public class CustomerValidator : AbstractValidator<Customer>  
  6.     {  
  7.         public CustomerValidator()  
  8.         {  
  9.             RuleFor(x => x.Name).NotEmpty().WithMessage("Name is required");  
  10.             RuleFor(x => x.Email).NotEmpty().WithMessage("Email is required");  
  11.             RuleFor(x => x.Email).EmailAddress().WithMessage("Email is not valid");  
  12.         }  
  13.     }  
  14. } 

After that, you need to create a controller's action methods; these render views on the UI and binds a model with the view. So let's create a controller with two action methods; these handle both request types (GET and POST) respectively.

  1. using System.Web.Mvc;  
  2. using FluentValidation.Results;  
  3. using MvcValidation.Models;  
  4. using MvcValidation.Validators;  
  5. namespace MvcValidation.Controllers  
  6. {  
  7.     public class CustomerController : Controller  
  8.     {  
  9.         public ActionResult Index()  
  10.         {  
  11.             return View();  
  12.         }  
  13.         [AcceptVerbs(HttpVerbs.Post)]  
  14.         public ActionResult Index(Customer model)  
  15.         {  
  16.             CustomerValidator validator = new CustomerValidator();  
  17.             ValidationResult result = validator.Validate(model);  
  18.             if (result.IsValid)  
  19.             {  
  20.                 ViewBag.Name = model.Name;  
  21.                 ViewBag.Email = model.Email;  
  22.             }  
  23.             else  
  24.             {  
  25.                 foreach (ValidationFailure failer in result.Errors)  
  26.                 {  
  27.                     ModelState.AddModelError(failer.PropertyName, failer.ErrorMessage);  
  28.                 }  
  29.             }  
  30.             return View(model);  
  31.         }  
  32.     }  
  33. } 

Thereafter I create a view (Index.cshtml) for user input under the Customer folder.

  1. @model MvcValidation.Models.Customer  
  2. @{  
  3.     ViewBag.Title = "Index";  
  4. }  
  5. @if (ViewData.ModelState.IsValid)  
  6. {  
  7.     <b>Name : @ViewBag.Name<br />  
  8.         Email : @ViewBag.Email  
  9.     </b>  
  10. }  
  11. @using (Html.BeginForm())  
  12. {  
  13.     <fieldset>  
  14.         <legend>Customer</legend>  
  15.         <div class="editor-label">  
  16.             @Html.LabelFor(model => model.Name)  
  17.         </div>  
  18.         <div class="editor-field">  
  19.             @Html.EditorFor(model => model.Name)  
  20.             @Html.ValidationMessageFor(model => model.Name)  
  21.         </div>  
  22.         <div class="editor-label">  
  23.             @Html.LabelFor(model => model.Email)  
  24.         </div>  
  25.         <div class="editor-field">  
  26.             @Html.EditorFor(model => model.Email)  
  27.             @Html.ValidationMessageFor(model => model.Email)  
  28.         </div>  
  29.         <p>  
  30.             <input type="submit" value="Create" />  
  31.         </p>  
  32.     </fieldset>  
  33. }  
  34. @section Scripts {  
  35.     @Scripts.Render("~/bundles/jqueryval")  
  36. } 

Let's run the application and test the following scenario:

1. When all fields are empty:

MVC-2.jpg

Figure 1.2: Validation Message when both fields are empty
 
2. When the Name field is empty but Email is not valid:

MVC-3.jpg
 
Figure 1.3 : Validation Message when Email is not valid

3. When both fields are valid:

MVC-4.jpg

Figure 1.4 All fields are valid


Similar Articles