Using ASP.Net MVC Validation Attributes outside of ASP.Net

comments

Some people love them, others absolutely hate them, but if you ask me one of the coolest features in ASP.Net MVC is the Data Annotations that you use to decorate your ASP.Net MVC classes for validation. But one of the coolest things that came along in .Net 4.0 was support for this across the whole framework – even outside of ASP.Net MVC!

image When working on projects outside of ASP.Net MVC its still just as relevant to write validation for your classes and their respective properties before you fire actions, communicate them to another class or simply add something to a database (among the 4 million other times validation can come in handy).

Taking what we know from ASP.Net MVC, we can easily add this functionality to the public properties of any class in any project in .Net 4, be it a Console App, Web Service, SilverLight, Windows Phone 7 – you name it.

This also means that any common libraries you use between multiple projects can have simple Data Annotations added in one place and validated everywhere – keeping your validation logic all in one place.

Getting down to business

In the project that holds the data model classes you want to add validation to, add a reference to the framework namespace System.ComponentModel.DataAnnotations

image 

Now open the class you want to add validation to.

We are going to add the following to it:

  • Add a class level meta data attribute telling our validator what type of class it is
  • Add your validation decorations to any properties exactly as you would in ASP.Net MVC

In my example below, i demonstrate how to do this with a class named Person. You can see I've added a MetadataTypeAttribute of type Person above the class declaration. I’ve also added a required field decoration to the public Name property of this class.

[MetadataTypeAttribute(typeof(Person))]
class Person
{
    [Required(ErrorMessage = "You must enter a name")]
    public string Name { get; set; }
}

Now I've got to create a new class that we will use to validate our decorated attributes against objects – in this instance our Person class above, but the same code will work for any class with the correct decorations.

Create a new class in your project and call is ClassValidator.

Paste the following code into that file:

public class ClassValidator
{
    public ClassValidator(object objectToValidate)
    {
        objectBeingValidated = objectToValidate;
    }

    private static object objectBeingValidated { get; set; }

    public List<ValidationResult> ValidationErrors { get; private set; }

    public bool IsValid()
    {
        if (objectBeingValidated != null)
        {
            ValidationErrors = new List<ValidationResult>();
            var context = new ValidationContext(objectBeingValidated, 
                null, 
                null);

            bool isValid = Validator.TryValidateObject(objectBeingValidated, 
                context, 
                ValidationErrors);

            if (!isValid)
            {
                return false;
            }
            return true;
        }
        return false;
    }
}

And we are done - That is all we need!

Using the Code

To use the above example, all you need to do, is create an instance of our ClassValidator and pass in the object we want to validate at initialisation.

We can then call the IsValid() method against it to find out if our class validates and a list of any validation errors will then be available in the public ValidationErrors property of our ClassValidator.

My example below demonstrates this usage in a console application that does the following:

  • Creates an instance of the example Person object
  • Doesn’t set any properties of this Person object (so our Name property will be Null - and therefore invalid)
  • Creates a ClassValidator and passes in my newly created Person, and then calls IsValid against it.
  • Prints all the errors found to the console.
Person p = new Person();

Console.WriteLine("Attempting to validate the person object");

ClassValidator validator = new ClassValidator(p);

Console.WriteLine("Is object valid of not?: {0}",validator.IsValid());

foreach (var error in validator.ValidationErrors)
{
    Console.WriteLine("Error in Person object: {0}", error.ErrorMessage);
}

Example Project

I have created a simple command-line application to demonstrate the above which can be found here.

I’d love to hear of any cool ways you’ve found to use this code.