Skip to main content

Validation with ASP.Net MVC2

I've blogged previously about the validation methods I've used on ASP.Net MVC projects and have recently been adapting this for use with version 2 of the framework.

One of the new features I wanted to make available was the use of data annotations for validation, where domain or view model classes can be decorated with attributes for validation of required fields, field lengths and range values. These can then be used for both server side and client side validation.

I ran into a problem with this though when validating entities that had related items - for example in my case I was working on a project management tool, where an entity such as a project is related to others such as a client and an account manager. The client entity has required fields such as a name, but when validating before saving the project entity I didn't really care about that as I was only interested in the client ID to perform the update operation.

The validation by default is set up to perform whole model validation, but a useful post from Steve Sanderson details how to get around this issue and perform partial validation based on just the values that are passed in the form post.

Data annotiation based validation isn't the the full story though - in a robust application it's considered necessary for the domain model to handle it's own validation too. This is partly a result of using techniques such as the above, which would allow a determined hacker to modify the form input to by-pass data annotation based checks on required fields.

In previous projects I've used straightforward C# code for the validation of model fields, but as I'd already used data annotions to define these rules it was a obvious violation of the DRY principle to have to do this again. .Net 4 provides a means of doing this using the Validator.TryValidateObject method.

For .Net 3.5 though I used a technique illustrated by JohnyO in this post on stackoverflow. It validates based on rules specified both directly on the class or in a meta data "buddy" class and thus allows the domain model to handle validation without repetition of all the rules.