Data Validation the Fun Way!

Let’s say you have a data model of a class that has two fields that are required. One of them is a string, let’s say “Name”, and the other is an int value, let’s say “Age”. And you have to validate these values before you pass them to the data layer to write to the database. How would you do it? Probably something like this (assuming XAML controls are bound to the properties):

Manual validation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public string Name { get; set; }
public int Age { get; set; }

void btnSave_Click(object sender, EventArgs e)
{
    StringBuilder sb = new StringBuilder();
    if(string.isNullOrEmpty(Name)) sb.AppendLine("Name is required");
    if(Age < 1 || Age > 99) sb.AppendLine("Age must be between 0 and 99");
    if(sb.Length > 0)
    {
        MessageBox.Show(sb.ToString());
        return;
    }
    DataLayer.SaveObject(Name, Age);
}

… wanna see how W2C does it?

DataValidationAttribute Validation
1
2
3
4
[Required(Error = "Name is required")]
public string Name { get; set; }
[Range(1, 99, Error = "Age must be between 0 and 99")]
public int Age { get; set; }

Yeah, I know, we rock. But really this took quite a bit of figuring out. Here’s the components that actually make it work:

  • IDataErrorInfo – this is a newish interface that WPF takes advantage of to validate controls once they update their data sources. There’s two methods, string this[string columnName] and Error, both which return either null / empty strings or a message. Most people use these methods to do the custom validation within them, a “if columnName == ‘Name’ && string.isNullOrEmpty(Name)” type of approach which is still kind of tedious, so I did more digging
  • DataAnnotationAttributes – also new to .NET, and primarily targeted at ASP.NET Dyanmic Data as well as Silverlight RIA applications, these define those [Required] and [Range] attributes we use (also RegularExpression, DataType, and StringLength), as well as give you a base class to create you own. The Dynamic Data and RIA controls are setup to use these automatically, but not anything else, so there’s one more component…
  • DataAnnotationValidator! – This is a group of methods that I borrowed from someone online and modified to use Generics so they work with pretty much any class with properties that you can throw at it. DataAnnotationValidator is setup to enumerate through a class’s properties, look for those Annotation Attributes, and perform the validations if any are found.

This validation action is actually performed by WPF automatically because we’re extending the IDataErrorInfo interface, so any time a bound control has its value changed it’ll check against the DataAnnotationValidator and update the control based on the result.

Comments