Over a million developers have joined DZone.

Testing Basic ASP.NET MVC View Model Validation With Brevity


I recently attended a Desert Code Camp session that introduced attendees to Rails (as in, Ruby on Rails). I’d gone through similar introductions before, but I needed a refresher and another perspective from another mouthpiece. I was reminded yet again that the bulk of the power of this thingamajig, Rails, is plain vanilla code generation. There is no shortage of code generators in the .NET world, and it is nothing new (tools like MyGenerationSoftware, CodeSmith, T4, et al, have been around for years) but the problem with code generators is that you have to go back to the code generator if you need to adapt and refactor as business requirements evolve and knowledge and understanding increase (or as sanity wanes while workarounds perpetuate, omg).

One feature of Rails stuck out at me again, however, and that is RoR’s approach to TDD in model validation. In the session, the speaker cobbled together a simple unit test, threw some one-liner validation rules into the model, “rebuilt” the app, and watched the red/green output spit out immediately upon build. Once the validation rules were properly applied to the model, this immediately showed up in the web view scaffolding. This is exactly the way all development should be—some Ruby enthusiasts believe that unit tests deprecate the applicability for strongly typed language compilation altogether, I think that’s ridiculous, but I love the idea of supplementing compilation with post-build unit tests as a standard practice, not to mention combining the fundamental object metadata with the behavior of core view functionality in any UI framework.

I looked again at ASP.NET MVC and, having done rather little with the supposedly great testability of the ASP.NET MVC platform, had to figure out how to apply what I had just seen in this RoR session to the ASP.NET MVC platform scenario. I already knew that ASP.NET MVC supports easy peasy validation metadata out of the box, using the System.ComponentModel.DataAnnotations namespace and the attributes therein to decorate the properties of my view models. Notice the [Required] and [RegularExpression] attributes in the stupid sample below:

using System.ComponentModel.DataAnnotations;  

namespace MvcApplication2.Models
public class Fiz
public string Name { get; set; }

public string Email { get; set; }

The problem, however, was that I was still green on how to actually validate that applying the ASP.NET MVC built-in validation functionality to an instance of this model actually works in a non-UI unit test. For example, let’s say I had not yet added the [Required] attributes in the above code yet, and, using red/green TDD coding practices, and I first create a unit test and execute this test (seeing red, or “Fail”) before applying the validation rule. What would such a unit test look like?

That is actually the main purpose of this blog post, if for no other reason than to have it for my own reference. ;)

The first example I came across explained that one would need to actually have the controller for this model in place, and an appropriate action, such as Create(), to capture the model. This controller would then be able to expose the ModelState property which would be able to return a property indicating IsValid.

// unit test code, but don't use this  
public void TestMyModel() {
var fizController = new FizController();
var unusedActionResult = fizController.Create(fiz);
Assert.IsFalse(fizController.ModelState.IsValid); // doesn't even work anyway without bringing out the Validator

The author of this example continued on to explain how to invoke the validator to fill in the missing functionality.

// My own flavor, does not require explicit controller.
// Still, don't use. Not where we want to be yet.

private class ValidationController<T> : Controller
public T Model { get; set; }

private Controller BindModelValidation<T>(T model)
var controller = new ValidationController<T>();
var validationContext = new ValidationContext(model, null, null);
var validationResults = new List<ValidationResult>();
Validator.TryValidateObject(model, validationContext, validationResults);
foreach (var validationResult in validationResults)
controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
controller.Model = model;
return controller;

public void TestMyModel() {
var fiz = new Fiz();
var validationController = BindModelValidation(fiz);

And that’s fine, except for the fact that the separation of concerns (model vs. controller) is instantly lost; except where custom validation behavior is declared on an overriding controller there’s really no reason to even look at controller logic here. What we want to test is the model’s validation metadata and behavior in the context of ASP.NET MVC’s existing plumbing, nothing more, since we already trust that Microsoft already QA’d ASP.NET MVC and its controller and validator classes.

Fortunately, inspecting this code it seems Microsoft did provide a Validator class with static methods exposed to validate a model based on its metadata. You don’t need to involve a controller at all. If you look closely, Validator.TryValidateObject(..), while being stupid in that you have to pass in a context object (even if you’re gonna instantiate a new throwaway one anyway), will return a list of validation failures, or ValidationResults. So why don’t we just validate the validation by validating that the count of validation failures is zero.

// Final code, I'm happy with this. Just need to move the  
// helper method ValidateModel() to a base class or
// somewhere else that's clean and out of the way and
// won't be copied/pasted.
public void EmailRequired()
var fiz = new Fiz
Name = "asdf",
Email = null
Assert.IsTrue(ValidateModel(fiz).Count > 0);

private IList<ValidationResult> ValidateModel(object model)
var validationResults = new List<ValidationResult>();
var ctx = new ValidationContext(model, null, null);
Validator.TryValidateObject(model, ctx, validationResults, true);
return validationResults;

Any reason why this won’t work? Any reason why Microsoft made brevity for validating model validation such an effort to be had?


Published at DZone with permission of Jon Davis, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}