Click here to Skip to main content
16,018,916 members
Articles / Desktop Programming / WPF

Validation in .NET Framework 4

Rate me:
Please Sign up or sign in to vote.
4.27/5 (7 votes)
18 Jun 2011CPOL3 min read 67.2K   788   57   12
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.

C#
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.

C#
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:

C#
/// <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:

C#
/// <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)


Written By
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.

Comments and Discussions

 
GeneralMy vote of 4 Pin
sachin10d12-Jun-11 23:53
sachin10d12-Jun-11 23:53 
GeneralAnother alternative Pin
pebrian2712-Jun-11 6:27
pebrian2712-Jun-11 6:27 
GeneralRe: Another alternative Pin
jim lahey17-Jun-11 3:25
jim lahey17-Jun-11 3:25 
GeneralHow does the Interface work? Pin
Mike Schnobrich2-Jun-11 10:18
Mike Schnobrich2-Jun-11 10:18 
GeneralRe: How does the Interface work? Pin
AbhishekGoenka2-Jun-11 18:31
AbhishekGoenka2-Jun-11 18:31 
GeneralRe: How does the Interface work? Pin
delimavi16-Jun-11 4:48
delimavi16-Jun-11 4:48 
GeneralRe: How does the Interface work? Pin
IAbstract17-Jun-11 4:18
IAbstract17-Jun-11 4:18 
GeneralThoughs about Validation Pin
DaProgramma3-May-11 0:36
DaProgramma3-May-11 0:36 
Validating single fields is the easy part. Most "validation" frameworks stop there.

- What if some condition "should" be met, but the data is not available at the moment? For example, we have field "insurance company" in our business object. New customer comes to our site, but does not know this detail right now. What should we do? Reject the whole form? Not a good idea. Although the insurance company definitely IS needed for any further processing, we should not enforce it at entry time. We need some means to indicate that this information is needed, but allow to continue.

- What if some condition is dependent on several fields? Obviously, it should be checked when the OK-Button is pressed.

Greetings
GeneralRe: Thoughs about Validation Pin
AbhishekGoenka3-May-11 4:39
AbhishekGoenka3-May-11 4:39 
GeneralRe: Thoughs about Validation Pin
Andy Missico16-Jun-11 12:19
Andy Missico16-Jun-11 12:19 
Generalhard-coding validation message is not a good idea Pin
Huisheng Chen23-Apr-11 13:11
Huisheng Chen23-Apr-11 13:11 
GeneralRe: hard-coding validation message is not a good idea Pin
AbhishekGoenka23-Apr-11 15:34
AbhishekGoenka23-Apr-11 15:34 

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

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