Click here to Skip to main content
Click here to Skip to main content

Validation in .NET Framework 4

, 18 Jun 2011
Rate this:
Please Sign up or sign in to vote.
Validation Frameworks in .NET Framework 4

Introduction

In the .NET Framework 4, a namespace called System.ComponentModel.DataAnnotations is available for both the common CLR (WPF) and the lighter Silverlight CLR. You can use the DataAnnotations namespace for various purposes. One of these is for data validation using attributes, and another is the visual description of fields, properties, and methods, or to customize the data type of a specific property. These three categories are classified in the .NET Framework as Validation Attributes, Display Attributes, and Data Modeling Attributes. This section uses Validation Attributes to define validation rules for objects

Using the Code

To use the DataAnnotations namespace, you need to add a reference to the assembly—that reference is not included in any Visual Studio project template by default. Then you need to decorate your objects with the correct attributes. As an example, the code below uses an incorrect approach of decorating a Domain Entity directly with these attributes. Next, I will refactor this code to make that entity unaware of its validation.

public sealed class Customer
{
    /// <summary>
    /// Gets or sets the first name.
    /// </summary>
    /// <value>The first name.</value>
    [Required(ErrorMessage = "The FirstName is a mandatory Field")]
    [StringLength(10, ErrorMessage = 
	"The FirstName should be greater than 10 characters.")]
    public string FirstName { get; set; }

    /// <summary>
    /// Gets or sets the last name.
    /// </summary>
    /// <value>The last name.</value>
     [Required(ErrorMessage = "The LastName is a mandatory Field")]
    [StringLength(10, ErrorMessage = 
	"The LastName should be greater than 10 characters.")]
    public string LastName { get; set; }

    /// <summary>
    /// Gets or sets the title.
    /// </summary>
    /// <value>The title.</value>
    [Required(ErrorMessage = "The Title is a mandatory Field")]
    public string Title { get; set; }
}

The Customer entity can be easily validated using a generic validator because you know that we want to validate only those properties that have a DataAnnotations attribute on them.

public sealed class GenericValidator<T>
{
    /// <summary>
    /// Validates the specified entity.
    /// </summary>
    /// <param name="entity">The entity.</param>
    /// <returns></returns>
    public IList<ValidationResult> Validate(T entity)
    {
        var results = new List<ValidationResult>();
        var context = new ValidationContext(entity, null, null);
        Validator.TryValidateObject(entity, context, results);
        return results;
    }
}

At this point, we can easily test the validator against the Customer entity, as follows:

/// <summary>
/// Determines whether this instance [can validate customer].
/// </summary>
[TestMethod]
public void CanValidateCustomer()
{
    Customer entity = new Customer { FirstName = "", LastName = "" };
    GenericValidator<Customer> target = new GenericValidator<Customer>();
    bool expected = false;
    bool actual;
    actual = target.Validate(entity).Count == 0;
    Assert.AreEqual(expected, actual,
    "The Entity should not be valid at this point.");
}

Refactor your Code – Good Approach

Now, to remove the validation from the Domain Entity, you need to create an interface that represents the Domain Entity and that includes the validation rules, and then inherit the Domain Entity from this interface. At the end of this process, you should be able to write code like this:

/// <summary>
/// Determines whether this instance [can validate customer].
/// </summary>
[TestMethod]
public void CanValidateCustomer()
{
    Customer entity = new Customer { FirstName = "", LastName = "" };
    GenericValidator<ICustomer> target = new GenericValidator<ICustomer>();
    bool expected = false;
    bool actual;
    actual = target.Validate(entity).Count == 0;
    Assert.AreEqual(expected, actual,
    "The Entity should not be valid at this point.");
}

Available Validation Frameworks

The validation technique that was just presented is only one of the techniques available for .NET. The advantage of using DataAnnotations is that it plugs into WPF and Silverlight perfectly, and it is designed in a way that works throughout all the layers of an MVVM application. In the ViewModel section, you’ll see why the DataAnnotations approach is the perfect match for WPF or Silverlight.

Another interesting framework created by Microsoft is the Validation Application Block, which is available with Microsoft Enterprise Library 5.0 (http://entlib.codeplex.com/). The Validation Application Block uses the same general approach—validating an object against a set of rules defined using attributes (data annotations) or an external XML file. The major difference from the DataAnnotations is the process you use to validate an object, but you should obtain the same final result.

Another framework, part of the open-source project NHibernate, is the NHibernate Validation Framework. This is available at http://sourceforge.net/projects/nhcontrib/ as part of the NHibernate Contrib project. The main disadvantage of using this framework is that unless you are planning to use NHibernate as your O/RM, you will introduce an additional dependency in your layers that might not be needed. This framework also requires you to sully your entities with validation rules related to a specific O/RM.

References

Summary

To sum up, it’s important to keep the Domain clean and unaware of the validation rules or methods you’re using, but it’s also important that you decide to use the appropriate framework for the type of application that you’re writing.

History

  • 22nd April, 2011: Initial version
  • 18th May, 2011: Updated References section
  • 16th June, 2011: Updated code

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

AbhishekGoenka
Architect
India India
I spent some time working as a programmer and computer developer for several IT companies. I gained a lot of knowledge and experience in the process, and met some very supportive people in the industry. In May 2000' I joined LBS College for Higher studies.
 
I enjoyed my studies as much as academic studies can be enjoyed. I feel that I depend my understanding of computers because of them. The LBS College gives his students a high level of studying, but my main problem with it is that its tests are sometimes completely out of sync with the material that is learned, too long and/or too hard, and so students receive low grades and are frustrated. This is especially demotivating considering the fact that studying there is a lot of work.
Follow on   Google+

Comments and Discussions

 
GeneralMy vote of 4 Pingroupsachin10d12-Jun-11 23:53 
GeneralAnother alternative Pinmemberpebrian2712-Jun-11 6:27 
GeneralRe: Another alternative Pinmemberjim lahey17-Jun-11 3:25 
GeneralHow does the Interface work? PinmemberMike Schnobrich2-Jun-11 10:18 
Excellent Article!
 
I have been trying to figure out how the Interface your describe works. It appears that the interface doesn’t allow inheritance of any attributes into the class. Could you show an example of the actual interface your talk about?
GeneralRe: How does the Interface work? PinmemberAbhishekGoenka2-Jun-11 18:31 
GeneralRe: How does the Interface work? Pinmemberdelimavi16-Jun-11 4:48 
GeneralRe: How does the Interface work? PinmemberIAbstract17-Jun-11 4:18 
GeneralThoughs about Validation PinmemberDaProgramma3-May-11 0:36 
GeneralRe: Thoughs about Validation PinmemberAbhishekGoenka3-May-11 4:39 
GeneralRe: Thoughs about Validation PinmemberAndy Missico16-Jun-11 12:19 
Generalhard-coding validation message is not a good idea PinmemberUnruled Boy23-Apr-11 13:11 
GeneralRe: hard-coding validation message is not a good idea PinmemberAbhishekGoenka23-Apr-11 15:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140709.1 | Last Updated 18 Jun 2011
Article Copyright 2011 by AbhishekGoenka
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid