FluentValidation

by MikeHogg 29. March 2013 20:56

I've always been kind of disappointed in my model class files in MVC after the first or second phase of a project, because the properties end up with so many DataAnnotation attributes that it's just easier to read an intellisense popup to see the class properties than view the code file directly.  And this is just with simple Display and Validation Attributes.

DisplayAttributes always seemed wrong to me just on principle.  It is putting Presentation Layer stuff in Domain Model files.  I always have to show the front end developers where this ‘default’ display attribute can be changed, and they are not used to looking at or modifying c# code.  For this reason, I’m torn on whether to continue to use Display attributes automatically.  But to help simplify my Model files, I would rather pull what model properties I need for my particular view out into ViewModel files, and put the attributes there. 

Validation Attributes are also tied to the Presentation, or User Input Layer.  Several times it happens to me that one page requires some validation, and another page using the same model, does not require validation (usually because it’s in read-only state on that page) and then I have to work around the validators.  These also belong in VM files.  So your Required Validators are only called where they are used.  Now your Model classes are clean, and should pretty closely resemble your data objects.

But- Validation isn’t strictly front end or presentation layer stuff, and so for further simplification, jump on the Fluent bandwagon, and take all those Validation attributes out of your ViewModel files and put them in FluentValidator classes.  It's really easy to set up, and the benefits you get are similar to Activity Based Authorization, in that all of your validation stuff is in exactly one place, and isn't interlaced in the display code of dozens of other presentation files.  Your Validation is now loosely coupled to both your presentation layer and your domain layer, and your code is easier to read and maintain.

Add the FluentValidationMVC to your NuGet, and let it pull in the dependencies.  Add exactly one line to your Application_Start

FluentValidation.Mvc.FluentValidationModelValidatorProvider.Configure();

and then put the attribute on your VM class itself,

[FluentValidation.Attributes.Validator(typeof(QuestionOptionValidator))]

And then create the validator class, and you can just enter all the validations, and nothing but the validations...

    public class QuestionOptionValidator : FluentValidation.AbstractValidator<QuestionOption>
    {
        public QuestionOptionValidator()
        {
            RuleFor(x => x.QuestionID).GreaterThan(0).When(qo => qo.ID != 0);
            RuleFor(x => x.ChartDisplay).NotNull();
            RuleFor(x => x.SpanishChartDisplay).NotEmpty().WithMessage("Please enter a Spanish Chart");
            RuleFor(x => x.CurrentlyViewedEventID).Must((q, currentlyviewedeventid) => q.IsActive && currentlyviewedeventid > 0);
            RuleFor(x => x.Description).Matches("^Desc.*$");
 
        }
         
    }

I don't need to paste examples, their docs are great.

http://fluentvalidation.codeplex.com/wikipage?title=Validators&referringTitle=Documentation&ANCHOR#Predicate

Tags:

MVC | Fluent

Add comment

biuquote
  • Comment
  • Preview
Loading

About Mike Hogg

Mike Hogg is a c# developer in Brooklyn.

More Here

Favorite Books

This book had the most influence on my coding style. It drastically changed the way I write code and turned me on to test driven development even if I don't always use it. It made me write clearer, functional-style code using more principles such as DRY, encapsulation, single responsibility, and more. amazon.com

This book opened my eyes to a methodical and systematic approach to upgrading legacy codebases step by step. Incrementally transforming code blocks into testable code before making improvements. amazon.com

More Here