Fluent Validation In ASP.Net MVC

Introduction

Validation is an important part of any web application. We have several approaches to implement validation in ASP.NET MVC applications such as Data Annotation and 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 can use when you want to treat validation logic as separate from the 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 so it has an advantage over data annotation.

This library is managed at GitHub and its also available as a Nuget package, so it's easy to add in a web application. Before moving to an example I would like to recommend you to have a look at my previous validation articles over ASP.NET MVC.

  1. ASP.NET MVC Server-Side Validation
  2. ASP.NET MVC Client-Side Validation
  3. ASP.Net MVC Validation Using Fluent Validation

Using the Code

I will create a UserViewModel model (UserViewModel class under Models folder) that has three properties, “Name”, "Email" and "Password" as in the following code snippet:

  1. namespace FluentValidationApplication.Models  
  2. {  
  3.     public class UserViewModel  
  4.     {  
  5.         public string Name { getset; }  
  6.         public string Email { getset; }  
  7.         public string Password { getset; }  
  8.     }  
  9. }  
Now we will install the Fluent validation Nuget package in the application, so I can use Fluent validation rules.

PM> FluentValidation
PM> FluentValidation.MVC5


Then I will create a validator class UserViewModelValidator for the UserViewModel model under the "Validation" folder, but you can create it anywhere in an application for validation rules on UserViewModel properties. I used three rules, one is not empty and the second validates an email address and third for password length. The following code snippet shows the UserViewModelValidator class.
  1. using FluentValidation;  
  2. using FluentValidationApplication.Models;  
  3.   
  4. namespace FluentValidationApplication.Validation  
  5. {  
  6.     public class UserViewModelValidator : AbstractValidator<UserViewModel>  
  7.     {  
  8.         public UserViewModelValidator()  
  9.         {  
  10.             RuleFor(x => x.Name).NotEmpty().WithMessage("*Required");  
  11.             RuleFor(x => x.Password).NotEmpty().WithMessage("*Required").Length(6, 10);  
  12.             RuleFor(x => x.Email).EmailAddress().WithMessage("Not Valid").NotEmpty().WithMessage("*Required");  
  13.         }  
  14.     }  
  15. }  
Then we will create a ValidatorFactory class that inherits the ValidatorFactoryBase class that is an abstract class. The following code shows the ValidatorFactroy class under the “Validation” folder.
  1. using FluentValidation;  
  2. using FluentValidationApplication.Models;  
  3. using System;  
  4. using System.Collections.Generic;  
  5.   
  6. namespace FluentValidationApplication.Validation  
  7. {  
  8.     public class ValidatorFactory : ValidatorFactoryBase  
  9.     {  
  10.         private static Dictionary<Type, IValidator> validators = new Dictionary<Type, IValidator>();  
  11.   
  12.         static ValidatorFactory()  
  13.         {  
  14.              validators.Add(typeof(IValidator<UserViewModel>), new UserViewModelValidator());  
  15.         }  
  16.   
  17.          public override IValidator CreateInstance(Type validatorType)  
  18.         {  
  19.             IValidator validator;  
  20.             if (validators.TryGetValue(validatorType, out validator))  
  21.             {  
  22.                 return validator;  
  23.             }  
  24.             return validator;  
  25.         }  
  26.     }  
  27. }  
The preceding code snippet has a static dictionary variable and static constructor. The dictionary type variable is a container for the validator classes of view models, here the value is IValidator that gets the validation rule at runtime on a view model. Here the advantage of the static constructor is that all the validation rules are registered on the respective view model once when the application runs.

Now we need to execute this validator factory constructor once when the application runs, so we will create its instance in the Global.asax.cs file as in the following code snippet.
  1. using FluentValidation.Mvc;  
  2. using FluentValidationApplication.App_Start;  
  3. using FluentValidationApplication.Validation;  
  4. using System.Web.Mvc;  
  5. using System.Web.Optimization;  
  6. using System.Web.Routing;  
  7.   
  8. namespace FluentValidationApplication  
  9. {  
  10.     public class MvcApplication : System.Web.HttpApplication  
  11.     {  
  12.         protected void Application_Start()  
  13.         {  
  14.             AreaRegistration.RegisterAllAreas();  
  15.             BundleConfig.RegisterBundles(BundleTable.Bundles);  
  16.             ValidationConfiguration();  
  17.             RouteConfig.RegisterRoutes(RouteTable.Routes);  
  18.         }  
  19.         private void ValidationConfiguration()  
  20.         {  
  21.             FluentValidationModelValidatorProvider.Configure(provider =>  
  22.             {  
  23.                 provider.ValidatorFactory = new ValidatorFactory();  
  24.             });  
  25.         }  
  26.     }  
  27. }  
Then, you need to create a controller's action methods; these render the view on the UI and binds a model with the view. So let's create a controller with two action methods that handle both request types (GET and POST).
  1. using FluentValidationApplication.Models;  
  2. using System.Web.Mvc;  
  3.   
  4. namespace FluentValidationApplication.Controllers  
  5. {  
  6.     public class UserController : Controller  
  7.     {  
  8.         [HttpGet]  
  9.         public ActionResult AddUser()  
  10.         {  
  11.             UserViewModel model = new UserViewModel();  
  12.             return View(model);  
  13.         }  
  14.   
  15.         [HttpPost]  
  16.         public ActionResult AddUser(UserViewModel model)  
  17.         {  
  18.             if(ModelState.IsValid)  
  19.             {  
  20.                 //Implement your application logic  
  21.             }  
  22.             return View(model);  
  23.         }  
  24.     }  
  25. }  
Thereafter I will create a view (AddUser.cshtml) for user input under the User folder.
  1. @model FluentValidationApplication.Models.UserViewModel  
  2.   
  3. <div class="panel panel-primary">  
  4.     <div class="panel-heading panel-head">Add User</div>  
  5.     <div class="panel-body">  
  6.         @using (Html.BeginForm())  
  7.         {  
  8.             <div class="form-horizontal">  
  9.                 <div class="form-group">  
  10.                     @Html.LabelFor(model => model.Name, new { @class = "col-lg-2 control-label" })  
  11.                     <div class="col-lg-9">  
  12.                         @Html.TextBoxFor(model => model.Name, new { @class = "form-control" })  
  13.                         @Html.ValidationMessageFor(model=>model.Name)  
  14.                     </div>  
  15.                 </div>  
  16.                 <div class="form-group">  
  17.                     @Html.LabelFor(model => model.Email, new { @class = "col-lg-2 control-label" })  
  18.                     <div class="col-lg-9">  
  19.                         @Html.TextBoxFor(model => model.Email, new { @class = "form-control" })  
  20.                         @Html.ValidationMessageFor(model => model.Email)  
  21.                     </div>  
  22.                 </div>  
  23.                   
  24.                 <div class="form-group">  
  25.                     @Html.LabelFor(model => model.Password, new { @class = "col-lg-2 control-label" })  
  26.                     <div class="col-lg-9">  
  27.                         @Html.PasswordFor(model => model.Password, new { @class = "form-control" })  
  28.                         @Html.ValidationMessageFor(model => model.Password)  
  29.                     </div>  
  30.                 </div>                  
  31.                 <div class="form-group">  
  32.                     <div class="col-lg-9"></div>  
  33.                     <div class="col-lg-3">                        
  34.                         <button class="btn btn-success" id="btnSubmit" type="submit">  
  35.                             Submit  
  36.                         </button>  
  37.                     </div>  
  38.                 </div>  
  39.             </div>  
  40.         }  
  41.     </div>  
  42. </div>  
Let's run the application and test the scenario:

add user
Figure: 1: Validation rules implemented on input fields

 Download

 You can download a complete solution for FluentValidation in ASP.NET MVC 5 using Dependency Injection from here