Saturday, September 14, 2013

FluentValidation for server side validation in dependency injection framework by "IValidatorInterceptor"

Today I will try to show you some important hidden feature of FluentValidation.First of all I have to tell you that I am also new to this concept.but as you know FluentValidation is really make you rock star in validation in mvc.simply because it has great seperation of concern (MVC always worry about that .. ;-)).

ok lets start the journy,
so I m try to say little bit domain knoledge about this.(where and when I got this problem and how do I solve it.)

when I join my new project in mvc we came across a following  problem.
This is my controller post action methord.
Ohh...There are lot of server side validations mess up my saving.... :( :(.


can we handle it in separately ? yes why not.

as you see there is a must operator that will help you to do some server side validation.yes.. :D
But My MVC use ninject dependency injection from controller.so I canot do any harm to my framework follows.

so in-order to do server side validation I must use this injected repository(this service mean mostly done serverside repository.)

now If you can undestand what I was fasing U might know What was my problem.ok let me tell you.

from model validator how can I get this injected service ??? :( :(.

after doing some research I fond that public
 class EmployeeModelValidator : AbstractValidator<EmployeeViewModel>, IValidatorInterceptor

has interface called  "IValidatorInterceptor" which has following methords.Which will give you much controll over binding.as you know before the controller being called the validation class will get call by the framework.if you are implementing this interface in your modelvalidator then you have more control over mvc binding.

 public ValidationContext BeforeMvcValidation(System.Web.Mvc.ControllerContext controllerContext, ValidationContext validationContext)
     
and

  public FluentValidation.Results.ValidationResult AfterMvcValidation(System.Web.Mvc.ControllerContext controllerContext, ValidationContext validationContext, FluentValidation.Results.ValidationResult result)

oh now prolem is over ??no.still I cant get the controller variables.as define in the controller.


   
but microsoft introduce dynamic key world in 2010.so by using that you can get pass the repository service.
now you can do what ever server side valdation that you need.injected from controller.

NB:

  • This is one usage of IValidatorInterceptor,but there are much more other.prime purpose of using this interface is to do some validation before and binding the model validation.
  • You have only one model validator for all your model validation in controller so be careful if you do editing also.
  • you can do further enhance to pass model parameter as follows, 
private bool IsNICAlreadyExist(EmployeeViewModel v, string NIC)
          which pass model to the your validation function.so your rule is like this,


  RuleFor(x => x.NIC).Matches(@"[0-9]{9}[vVxX]").WithMessage("Enter valid NIC number ").Must(IsNICAlreadyExist).WithMessage("NIC already exists in the application");

this is one methord of doing that if you have other methords please commet me. thank you.
here for this I do thanks to my teq lead askar mustafa.