Automatic Fluent Validation Integration into ASP.NET MVC with MvcTurbine.FluentValidation

I’m a big fan of Fluent Validation, a .Net library written by Jeremy Skinner that makes validation easy and understandable.  If you’ve never seen it, here’s a quick example that should explain it:

public class LoginInputModelValidator : AbstractValidator<LoginInputModel>{
   public LoginInputModelValidator() {
      RuleFor(x=>x.Email).NotEmpty();
      RuleFor(x=>x.Password).NotEmpty();
   }
}

That’s all there is to validating a login form, at least to the point to making sure the email and password were both entered.  See how easy that is?  But the thing is… how do you use it with ASP.NET MVC2?  How do you make its use seamless with the framework?

Well, like most, I started with Jeremy Skinner’s post on MVC2 integration.  He explains how to create your own IValidatorFactory and what code to enter in your global.asax file.  Great help, but couldn’t it be easier?  Do I really want to copy bits of code here and there in each MVC project?  What if I switch IoC containers?  It works, but it didn’t feel like a complete solution to me.

So… I put it on myself to come up with the solution I wanted.  I’m also a big fan of MVC Turbine, a project that integrates IoC throughout your MVC application (which is essential).  MVC Turbine offers the concept of a “blade” that lets you inject code into the startup and the setup of your favorite IoC container.  Essentially, it gives you one place to inject functionality that can then be used throughout your application.  Functionality like… implementing Fluent Validation into your MVC application!

MvcTurbine.FluentValidation

My solution is MvcTurbine.FluentValidation, and the source and binary can be found at here on GitHub.  In order to use it to automatically validate your MVC app, you’ll need to do the following:

1.)  Setup your ASP.NET MVC application to use MVC Turbine (which you should do anyway).

2.)  Add a reference to MvcTurbine.FluentValidation.dll.

That’s it.  Really, that’s it.  By adding MvcTurbine.FluentValidation.dll to your application. MVC Turbine will add the FluentValidationBlade to your application startup.  That blade will scan your project for validators, create an implementation of the IValidatorFactory using your preferred IoC container, create an model validator provider, and incorporate everything into the application.  And to top it all off, it will instantiate your validators through your IoC container, giving you the ability to add dependencies like this:

public class LoginInputModelValidator : AbstractValidator{
   public LoginInputModelValidator(IMembershipService membershipService) {
      RuleFor(x=>x.Email).NotEmpty();
      RuleFor(x=>x.Password).NotEmpty();
      RuleFor(x=>x.Email).CheckThatThisIsAValidEmail(membershipService);
      RuleFor(x=>x.Password).CheckThatThisIsAValidPassword(membershipService);
   }
}

The blade and Turbine does everything for you, leaving you to just use it.  If I added MvcTurbine.FluentValidation to my project, simply having that validator somewhere in my project is all it takes to integrate it with an action that needs it, like this:

[HttpPost]
public ActionResult Index(LoginInputModel inputModel)
{
   if (ModelState.IsValid == false)
      return View("Index");
   membershipService.LogInAsUser(inputModel.Email, inputModel.Password);
   return RedirectToTheHomePage();
}

My validator will have run before the Index action was invoked, and ModelState will be loaded with any errors from the validator.  The validator even checked the email & password combination, keeping my controller clean.  Easy as pie.

The Bigger Picture

If you look at the code to this library, you’ll see a grand total of three classes.  There’s not much there.  I’m leveraging what Fluent Validation, MVC Turbine, ASP.NET MVC, and the many .Net IoC containers  already offer.  I think there is something special here, though, and it’s MVC Turbine’s role as the glue holding them all together.  By hooking into the ASP.NET MVC Pipeline at the appropriate places and abstracting away the registering and resolving of classes from the IoC container, it makes these types of integrations possible.  I’ve written a few of these integrations, and I can tell you — they all, pretty much, turn out like this.  You just get what you need into the right spots, and then you move on.

It deserves more discussion than I can give now, but that’s a more important point than this particular solution.  If you have integrations in MVC where you find yourself having to edit things in multiple places, or if you find yourself continually running to global.asax everytime you want to change something, you need to give MVC Turbine a look.

Download MvcTurbine.FluentValidation here.

Tags: , ,

13 Comments

  • Great blog post! I’m going definitely use this blade for our apps going forward; it will make things a lot easier across our edit/create forms!

  • Charles Ouellet says:

    Nice post!

    Personally, I prefer nvalid fluent validation library.

    http://www.nvalid.net

    It should be easy to implement this library the way you did with FluentValidation

  • Darren says:

    Thanks Charles, NValid nvalid library looks good! I’ll check it out and see if I can make a blade for it as well.

  • Erx says:

    Will this make it possible to use fluent validator and mvc validation side by side on the same model? If so that would be great. If not, do you think you could figure this out as I have tried many times and did not succed. Mvc attribute style validation for the simple stuff just reads much better, then I would just us FV for complex stuff like validating multiple properties etc as mvc is real weak on that end.

    What do you think?

  • Darren says:

    Erx, it does indeed use Fluent Validation and MVC validation side-by-side on the same model. So like you say, you can use data annotations to mark your model for simple rules (like [Required]), and then use Fluent Validation for the more complex stuff. Both validations will run and both will be loaded into ModelState.

    The code that does this is in the FluentValidationBlade.cs, in the code below:

    private static void AddAFluentValidationModelValidatorProvider(IRotorContext context)
    {
       var fluentValidationModelValidatorProvider = CreateFluentValidationModelValidatorProvider(context);
       ModelValidatorProviders.Providers.Add(fluentValidationModelValidatorProvider);
    }
    

    ModelValidatorProviders is in the MVC framework, not Turbine, so you can actually add as many validators as you want.

    Personally, I prefer to pick one method for validation, just to make the tests clear. If I write a class that validates an input model, but it in fact only validates half of the object, then it looks to others like it is incomplete OR half of your validation will have to run through something completely different than the other rules. I know how you feel, though. I made a few helper methods like .Required (instead of [Required]) to make Fluent Validation feel as comfortable as possible to my coworkers who want to use more MVC-standard stuff.

    And it looks like Fluent Validation is more work, but it’s really pretty easy. For example, watch me write a validator that just tests that first and last name are required in less than 60 seconds. Ready, set, go….

    public class ModelValidator : AbstractValidator{
       public ModelValidator(){
          RuleFor(x=>x.FirstName).Required();
          RuleFor(x=>x.LastName).Required();
       }
    }
    

    DONE! 43 seconds. Fluent Validation also has some neat testing extension methods, too, so I know I can test this with no trouble.

  • Liam says:

    Great blog post and the blade library! It probably couldn’t get much easier than using this.

  • Erx says:

    darren, thank you for your detailed reply. its good to find people to discuss these under documented and may i say incomplete areas of asp.net mvc :) .

    although it may seem you can add many validators, and you can, to the collection, and there appears to be no problem there. however, when i was actually running the validations, the validation which ran first was always the validation framework that worked, and the other framework would just not work. in otherwords, it was first run best served.

    for instance, if i ran the inbuilt mvc validators first, then all hte FV stuff that exists were ignored, even tho the validator was added to the collection in the global.asax file. if i ran the FV first, then all built in mvc validation attributes were ignored. i could never get them working together. i tried setting up the buddy classes, class structures, combining, seperating etc in as many possible ways/combinations that i could think of in the hopes that it would make it work, not knowing why it doesn’t. but non of these worked.

    although i have not tried it with tubine, my question to you is, have you actually seen it work together on the same model with or without turbine?

    to elaborate on my need/desire to do this, ive found several issues with FV where it doesn’t like to work, and had to use non-conventional ways to do things in FV with kills client-side validation (awch), don’t get me wrong, FV is great, and jeremy skinner is a fantastic guy and responds to questions with great care on his discussion blog, but it had several drawbacks on simple validation stuff, however, excels greatly on complex validation, which is what i would like to use it for.

    so, my question to you is, have you seen it work and if so i’ll be testing it straight away. i really think it would be an mvc developers wet-dream to be able to use datannotations and fluentValidator together lol.

  • Darren says:

    I have seen both the Fluent Validation and the standard MVC validation work together, but after playing with it a bit this morning I found a few issues. Here is what I found:

    Condition #1: Using MVC data annotations with an empty FV class.

    Success, the validation worked and the error messages appeared by the fields as expected.

    Condition #2: Using FV class without MVC data annotations.

    Success, the validation worked as expected.

    Condition #3: Using Fluent Validation and data annotations together. I made one field required through FV and one required with data annotations.

    Fail. The validation ran through validators and both fields were marked as error. However, I was only able to see the errors from the FV. So, in other words, I had two fields that were required, but only one showed the error message.

    It appears you are right, they don’t work together as well as I thought. I haven’t done client-side validation with either, so it’s very possible that they won’t work there as well. It seems like it will only work if you do either-or, but maybe not. The only thing I can say for sure is: It works if you use Fluent Validation only.

    There is some hope, I guess, in that both are open-source so it should be possible to fix whatever’s breaking right now. Sorry for the confusion, though!

  • Erx says:

    darren, thats ok, i appreciate you looking into and testing this to confirm my experience.

    would be cool though if anyone can figure out a way to get both working, if anyone does do let us all know!

  • [...] Cauthon Contact Me « Automatic Fluent Validation Integration into ASP.NET MVC with MvcTurbine.FluentValidation [...]

  • Thanigainathan.S says:

    Hi There,

    Can you be little clear whether this Turbine is validation factory ?
    Thanks,
    Thnai

  • Darren says:

    I’m not sure what you mean. MVC Turbine is a framework that injects IoC into all of the components in ASP.Net MVC. So things like controllers, action filters, etc. will all be instantiated with your preferred IoC container instead of just being new’d up.

    MVC Turbine also provides a mechanism for injecting functionality into your application through use of a “blade.” That’s not too complicated, either. It’s like a class that gets a chance to do all of the things that a programmer would normally pile into global.asax.

    That’s all MVC Turbine really is. What I did here was use the “blade” mechanism to set up Fluent Validation into MVC. Does that help to differentiate the two?

  • Nick Riggs says:

    @Erx, @Darren

    Darren, nice article.

    Other validation libraries not playing 100% nice with annotations is one of the reasons I built Foolproof Validation. The source is out on CodePlex:

    http://foolproof.codeplex.com/

    Hope it helps.

Leave a Reply