Introduction

As architects and developers of enterprise systems, many of us spend countless hours evaluating best practices, security schemes, exception handling, logging and the best approach to the segmentation of software tiers. However, we often overlook one of the most important aspects of all, validation. Without the proper validation of inputs into our system, we can easily introduce bugs, leave ourselves open to hackers, and/or corrupt the state of our system.

ASP.Net made huge leaps forward with the introduction of validator controls; however, what if you are working outside the user interface tier in the business logic layer or the data access layer? How do you handle validation when you don’t know who all of your clients are going to be?

This article will describe and promote a common validation framework for the validation of method parameters, class properties and fields. To do this the article will provide a high-level overview of the different pieces of the validation framework and how they fit together. Interspersed with this overview is a discussion of the .NET features leveraged; such as, Reflection and custom attribute types. Finally, we will delve into a more detailed discussion of how some of the more important pieces of the validation framework work together.

For a complete listing of all code described in this article, please visit my website at www.cybral.com/solutions/tools.htm


Overview

As already mentioned, we are going to leverage facets of the .NET programming model including Attributes and Reflection. Specifically, we are going to define our attribute types that encapsulate the validation behaviors we seek. We are then going to attach these validation attribute types to method parameters, properties and fields in order to associate what we want validated with the rules that govern their validation. After this, we are going to specify where we want validation to occur by specifying, in our code, an instance of a validation class (discussed later in the article). This validation class will, at runtime, leverage the .NET System.Reflection namespace in order to find our attribute types and perform the necessary validation based on runtime values. This enables a consistent approach to validation and helps streamlines your implementation code.

If you already know what reflection and custom attribute types are, you may want to skip the next sections “What is Reflection” and “What are Attributes”. If not, the following sections give a quick overview of what they are and then point you in the right direction for more detailed information.

What Is Reflection?

As its name implies, Reflection is a discovery mechanism providing the means to “reflect” upon information about a .Net data type regardless of its defining language. This functionality is provided through the namespaces System.Reflection and a core construct of the .Net Framework. Through this namespace, run-time inspection of nearly all .Net constructs can occur.

I would be delinquent if I did not mention the fact that there is another powerful aspect of reflection, Emit. The System.Reflection.Emit namespace provides the ability to “Emit” metadata and Microsoft Intermediate Language (MSIL) on the fly. You are literally generating code when you do this. However, we will not be emitting code in this article.

We will go into more detail of how to use reflection in this article; however, there is a great deal of information on the Internet about this subject and the following MSDN link is a good place to start Reflection Namespace from MSDN.

What are Attributes?

The Microsoft Attributes Tutorial defines attributes as

“…a powerful method of associating declarative information with C# code (types methods, properties, and so forth). Once associated with a program entity, the attribute can be queried at run time and used in a number of ways.”

This feature is so ingrained into the .NET framework that there are a number of Attributes available to you out of the box. For example, when you create a new WebService, you may have noticed that the code generated for you has WebMethodAttribute assigned to your webservice method. When the compiler notices this attribute, it exposes your method as a WebService. So whether you realize it or not, you are using attributes.

The second part of the definition, “….the attribute can be queried at run time and used in a number of ways.” is telling you that you must use reflection in order to find the attributes. This is a key concept. Attributes by themselves don’t do too much. They must be coupled with reflection and then acted upon in order to provide a meaningful implementation. Hopefully, you will see this as the article progresses.

For more information on Attributes, I recommend the following links:
System.Attribute Class
Extending Metadata Using Attributes
Repurposing Enumerations (uses Attributes)
FunwithAttributeBasedProgramming by DonXML


Why Validators

When I hear the term “defensive programming”, I automatically think of validation. It’s true, whether we like to admit it or not when we are developing an architecture, we should…we must…spend cycles in the design, programming and testing of a validation scheme. At the very least, failure to properly validate input will produce bugs. At the very worst, it will crash or corrupt your system.

As discussed, a solid architecture must create and promote a common validation scheme. When you think of validation, you can take a page from ASP.Net and follow the 80-20 rule. Specifically, 80% or more of what you will need can be satisfied with a few well thought out classes. For example, ASP.Net delivers the following classes out of the box:

Believe it or not, these four validators handle much of what a typical ASP.Net client will need. Our design will define a similar set of validators; as you will soon see.


Why Not Leverage ASP.Net Validators?

It would be wonderful if we could leverage the ASP.Net validator controls to our ends. However, this will not work. The ASP.Net validator controls have a different charter. They leverage the ASP.Net Event Model, JavaScript and HtmlWriters in order to provide both client and server side validation. ASP.Net validators must also be bound to other controls in order to work. In a sense, our job is easier. We don’t have to inject Html and JavaScript code into the Html Stream being sent to the client! However we also have a set of our own problems, as you will soon see.

There is quite a bit of debate surrounding the issue of validation and how it should be implemented in the middle tiers. Should we raise an exception? Should we return a collection of error messages? While ASP.Net validator controls has its hands full dealing with both client and server side validation, it does have the luxury of a page to capture and display error state. In the middle tiers, capturing and displaying error state is a bit more onerous. Do we return a collection of error messages and let the client figure out how to display it to its clients? Or do we raise an exception with the error information as part of the message text? The answer is both. For example, if I am developing a method in my business logic layer or service layer and the input given to my service was incorrect, I will probably want to throw some type of ValidationException. However, if I am a web developer and I am developing a web page, I may want to validate the state of an object and report it back to the client via the ASP.Net ValidationSummary control or a similar mechanism without throwing an exception.

For the purpose of this article, the business logic layer is the implementation of business logic and it is responsible for executing the necessary logic to carry out the business rules of the system. A service layer is analogous to the implementation of service oriented architecture, SOA. For more information on SOA, I recommend A guide to developing and running connected systems with Indigo. It is within the context of Indigo but it gives a nice description of SOA.

Details

Since we are working in the middle tiers and exposing a Service Layer and/or a Business Logic Layer, we will want to validate method parameters. However, there will be times when we want to validate a class’s properties and fields. We also need to discuss major aspects of the design and develop a class model. The class models are shown below; but the major chunks of the design are:

Example

Before we go further, it would be a good idea to show the validation framework in action. The following is a small piece of code that shows how to attach validation behaviors to a method’s parameters and then validate them.

The following piece of code shows three ways to use a validator. In real-life you would only use one of them. I just put them in one place so I wouldn’t have to create three separate code snippets (I know. I know. I am exceptionally lazy). So when implementing, just pick one.
Code Snippet 1
public void SomeMethod (
		[RegExAttribute("[a,e,i,o,u]",RegexOptions.None)]string someParameter)
{
		// Class to perform validation.
		MethodValidator validator =new MethodValidator(
			MethodBase.GetCurrentMethod(),someParameter);

		//1) This throws a ValidationException if there are errors.
		validator.Validate();

		// 2) Enumerate the list of messages....You can also just grab the collection.
		foreach(string s in validator.DetailMessages) Debug.WriteLine(s);

		// 3) Check if it's valid and then display a message.
		if(!validator.IsValid())
		{
			// do something about it. For example, get a formatted error.
			string message=validator.GetFormattedError();
		}
}

Code Snippet 1 is doing a couple of things for us. First of all we are using the RegExAttribute validator class to state that only the values a, e, i, o and u are allowed for string parameter ‘someParameter’. Second, within the function body we are running up an instance of the MethodValidator class. The constructor of this class takes the Meta definition of the method we are evaluating (e.g. MethodBase.GetCurrentMethod()) followed by the list of all parameters for the method.

The MethodValidator class in this example performs all of the heavy lifting. It uses the meta definition of the method returned back via MethodBase.GetCurrentMethod() to reflect upon all of the parameter definitions looking for our validation attributes. It then validates the values passed in against the validation attribute types.

I thought about trying to snag the parameter values off of the stack so that they would not have to be passed in via the constructor, but why bother. Since I have access to the parameter values here I took the easy way out and just passed them in via the constructor.

After construction, you have a couple of choices:

  1. Call Validate(). This method will throw a ValidationException listing all errors encountered. Or
  2. Access the collection of errors via the DetailMessages property. If there are no errors, the collection will have a count of 0. And/Or
  3. Call IsValid(). This tells you whether or not an error exists but it does not raise an exception. It is up to you to act up on the return from this method call. And/Or
  4. Get a single formatted message listing all errors via the function call GetFormattedError().

Attributes/Behaviors

In our example we will be assigning validation behavior to class items such as parameters, properties and fields. To do this we will leverage a facet of the .NET assembly model that allows us to write our own attribute types, commonly called custom attribute types. To assign validation behavior, we will encapsulate our desired behaviors into small classes we will call validation attributes. Instances of these attributes have a simple mission in life. They encapsulate the specific validation behavior we are seeking and provide the ability to attach themselves to items we deem appropriate. However, custom attributes are not enough. They are powerful tools for adding behaviors and commands to class items such as parameters, properties and fields; however, they lack their own path of execution. In other words, now that I have them, what do I do with them? To make Custom Attributes useful, you must do two things: 1) Reflect upon them. And 2) Act upon them. In the previous section I showed you an example of the Validator class. This validator class was responsible for reflecting and acting upon our validation attribute types. In the next section we will delve into the Validation Process more thoroughly.

In order to create a custom attribute type we must derive from the .Net class System.Attribute. Once derived, we have access to the rich feature set of the .Net runtime. Our model will create a base attribute type called BaseItemAttribute. This will enable us to query for just the attributes that belong to the validation framework.

BaseItemAttribute has the following definition (with a description of salient points in Table 1):

Figure 1


Table 1
A description of Methods and Properties of BaseItemAttribute.

# Name Type Description
1 Name string The name given to the attribute. The validation process will assign the TypeName of the attribute if one is not give. This means that if you ever attach multiple attributes of the same type, then you must assign each item a unique name. If you do not the validation process will throw an ArgumentException and give a “Programmer Error” message.
2 ErrorMessage string This is the unformatted string message used to create an error message. Depending upon the class, it may contain formatting characters. To get the error message without any formatting characters, use GetFormattedError().
3 IsValid(object val) bool This virtual method returns true or false depending upon whether or not the value provided passes its validation rules.
4 GetFormattedError(object val) string This virtual method returns a string message defining what and why the value did not pass validation. It uses the formatted string defined in the property ErrorMessage to construct the returned message. By changing the ErrorMessage property you can effect change to the FormattedError returned. Each derived class can override the GetFormattedError method in order to add additional items a client can use for the error message.

Figure 2
The Attributes delivered with the framework are shown in figure 2. Each Attribute type has a single function to perform and they loosely correlate to what ASP.Net provides with their validating controls. Table 2 provides more details of each class.

(Click to see larger image)


Table 2 - A description of the Attribute Classes

# Name Description
1 Attribute Part of the .Net System namespace. All custom attributes must be derived from this class.
2 BaseItemAttribute Abstract Base class for all validating attributes.
3 BaseRangeAttribute Abstract Base class for all validating range attributes
4 RegExAttribute This attribute enables you to use a regular expression as the basis for validation.
5 ValidDateTimeAttribute This class enables you to validate that a string is in a valid DateTime format.
6 RequiredItemAttribute Validates that the given value is not null. If the item is a string, it makes sure that the item is not null and its length > 0.
7 Int32RangeAttribute Validates that a given value is a 32 bit integer value or can be converted to a 32 bit integer value and falls within the range specified during construction.
8 Int64RangeAttribute Validates that a given value is a 64 bit integer value or can be converted to a 64 bit integer value and falls within the range specified during construction.
9 DoubleRangeAttribute Validates that a given value is a double value or can be converted to a double value and falls within the range specified during construction.
10 StringLengthAttribute Validates that a given value is a string or can be converted to a string and has the length specified during construction.

Note: Although not a requirement, it is a .NET convention to append “Attribute” to the name of each custom attribute type class. Then when assigning an attribute to an item, you may leave off the “Attribute” portion of the name so that you can decorate your items in the following manner [RequiredItem()] or [RegEx(….)]. This feature has a side effect. If you define two attribute type classes, one with the name RegExAttribute and the other RegEx you will be able to compile your project; however, when you attempt to use the class RegEx, you will get the following compilation error:

’RegEx’ is ambiguous; use either ‘@RegEx’ or ‘RegExAttribute’

I recommend you follow the .NET convention; regardless, it is a good idea to pick a single convention and stick with it.

So far we have defined the different core attributes types delivered with the Validation Framework. Now it is time to look at some implementation code. One of the simpler and most used classes is RequiredItemAttribute and its implementation code looks like this (comments removed for brevity):

Code Snippet 2
public class RequiredItemAttribute:BaseItemAttribute
{
     ..................
     public override bool IsValid(object val)
     {
		//always check for null
		if(val!=null&&val.GetType()==typeof(string))
			return (Convert.ToString(val)).Length>0;
		else
			return val!=null;
     }
     public virtual void Validate(object val)
     {
     	if(!IsValid(val)) throw new ValidationException(GetFormattedError(val));
     }
}

These classes are meant to be lightweight and easy to implement, so there isn’t much code. It is also important to point out that these commands do not maintain state about the values they are validating. They only care about answering the question “Is the value valid?”, and the answer must be true or false. This functionality is presented in the method IsValid(object val). Notice that it first checks to see if the value is null. If it is not null, it returns false. If it is NOT null, then it determines if it is a string. If it is a string, it checks its length. If its length is 0, then it also returns a false.

Strings are a bit special with .NET. In many ways they act like a reference type (e.g. can be null), but if they are not null they can have a length of 0. However, if the item is required is a 0 length string valid?

Validation Process

Custom Attributes are a powerful tool for adding Behaviors and Commands to class items such as parameters, properties and fields and as described above, they lack their own path of execution. We also mentioned our need to: 1) Reflect and then 2) Act upon our custom attribute types.

To reflect upon them, you use the System.Reflection namespace as described above. To act upon them, you need a design that provides the hooks to your validation process. The hook to start the validation process caused me some anguish. In the end, I opted for the most simple and straightforward design. Specifically, I decided to expose a set of classes and make the developer write the code to start the validation process.

An interesting aspect of the Validation Process design is that it is organized in the same vein as the System.Reflection namespace. This makes sense. For example, there is a System.Reflection.MethodBase class and derived from it are the classes System.Reflection.ConstructorInfo and System.Reflection.MethodInfo. These classes provide information on; you guessed it, Constructors and Methods respectively. Since we will be validating both constructor and method parameters, it made sense to follow a similar organization.


Figure 3

Table 3 – A description of the Validator Classes

# Name Description
1 TypeInfoValidator Abstract class is the base class for our Validation classes.
2 MethodBaseValidator Abstract class is the base class for the validation of all methods.
3 ContructorValidator Validates constructor parameters.
4 MethodValidator Validates method parameters
5 ClassValidator Validates all properties and fields of a class.
6 PropertyValidator Validates a property.
7 ClassItem Maintains Context between the System.Type being evaluated, the list of attributes associated with the Type and the value validated.

Using a Validator

Determining which validator to use is intuitive. For instance, to validate a method’s parameters, use MethodValidator. To validate a constructor’s parameters, use ConstructorValidator. To validate a Property, use PropertyValidator and to validate all fields and properties of a class, use -you guessed it - ClassValidator. You may wonder why there is a ConstructorValidator and a MethodValidator. Aren’t they really the same? In a sense they are and my first design actually had a single class handling both. However, I quickly ran into issues and ended up giving them their own implementation. Furthermore, the System.Reflection namespace makes a similar distinction. So I am in good company.

Context

If you look closely at the Validator class model, you will notice the type ClassItem. This class is used extensively throughout the Validator class model. For instance MethodBaseValidator.Parameters and ClassValidator.Properties are actually collections of ClassItems. A ClassItem maintains what I call Context. It maintains the context between the System.Type being evaluated, the list of attributes associated with the Type and the value being validated. Take a look at the code for the ClassItem class located at www.cybral.com/solutions/tools.htm.

Constructing a Validator

At this point, we have defined how we create Commands, the Validators used to carry out the validation process and how the Validators maintain context between the Type being evaluated, its attributes and the value validated. Now, let’s look at some more code. The construction process for all Validators is about loading the information it will need to validate code and getting detail messages about invalid conditions. After construction, you merely need to call into IsValid, Validate(), GetFormattedError() or DetailMessages.

The following is the code for the MethodValidator’s constructor. The parameter object[] list contains the values being validated. This code demonstrates how it will load the information it needs to perform validation for a method. For the other classes, please download the code and have a look-see. They follow a similar process.

Code Snippet 3
public MethodValidator(System.Reflection.MethodBase methodBase,
		params object[] list):base(methodBase)
{
	// using Reflection, get the parameters
	ParameterInfo[] parameters = methodBase.GetParameters();
	// enumerate the list of fields, validating each one of them
	for( int i=0;i<parameters.Length&&ilist.Length;i++)
	{
		// get parameter object
		ParameterInfo parameter = parameters[i];
		// build the classitem by calling the factory method ClassItem.Create
		ClassItem classItem=ClassItem.Create(parameter.Name,parameter,list[i]);
		// add this Item to the parameter collection.
		_parameters.Add(parameter.Name,classItem);
	}
}

Description: I used a factory like pattern to implement the creation of a ClassItem. This helped simplify things tremendously. The parameter ICustomAttributeProvider is an interface defined by the .Net Framework. When reflecting on an item, the items returned by the .Net framework will implement this interface. This enabled me to use a strongly typed DataType as a means for reflecting upon the custom attributes associated with an item. This is what I am doing below.

public static ClassItem Create(string name,ICustomAttributeProvider item,object val)
{
	// create Item object to add to internal collection
	ClassItem classItem=new ClassItem(name,val);
	// now get attributes we care about for each field
	BaseItemAttribute[] attributes=(BaseItemAttribute[])item.GetCustomAttributes(
			typeof(BaseItemAttribute),true);
	// now enumerate the list of attributes
	foreach(BaseItemAttribute attrib in attributes)
	{
		// if the attribute does not have a name, give it the name of the parameter.
		if(!attrib.IsNameSpecified())attrib.Name=name;
		// we store the classitem by the name of the type.
		string typeName=attrib.GetType().Name;
		// check for duplicates.
		if(classItem.Contains(typeName))
				throw new ArgumentException(string.Format(
						__duplicateAttributeNames,name));
		// now add it.
		classItem[typeName]=attrib;
	}
	return classItem;
}

IsValid

Now that the Validator class has the information it needs to validate, let’s take a look at the code that determines if something is valid. The code snippet below looks at how we check if methods and constructors have valid parameter values.

Notice that we are merely enumerating the list of ClassItems asking each one if it is valid. The first one that is not valid will cause it to immediately return false.

Code Snippet 4 - MethodBaseValidator.IsValid()
public override bool IsValid()
{
	foreach(ClassItem parameter in _parameters.Values)
	{
		if(!parameter.IsValid())return false;
	}
	return true;
}

Description: Remember ClassItem? This item merely enumerates its list of attributes and asks each attribute type if it is valid. Again, it returns upon the first occurrence of an invalid item.

ClassItem.IsValid() Method
public override bool IsValid()
{
	foreach(BaseItemAttribute attribute in _validatorAttributes.Values)
	{
		if(!attribute.IsValid(this.Value))return false;
	}
	return true;
}

Validate

I would be remiss if I didn’t point out the Validator code. All it does is call IsValid() and throw a ValidationException if it is not valid. To format the ErrorMessage, GetFormattedError() is called. This method delegates to all attribute classes so that each attribute that reports a failure can add its message to a list of messages to get formatted.

There is actually quite a bit to implementing a common scheme for message formatting. For example, I defined an interface IValidatorFormatProvider and the concrete class MultiItemFormatProvider to handle the formatting of multiple messages. With this framework you can also provide your own class. The discussion of this functionality is outside the scope of this article but well worth a look at the code if you are so inclined.
Code Snippet 5 - Validate() method
public virtual void Validate()
{
	if(!IsValid()) throw new ValidationException(GetFormattedError());
}

What about Interception?

Some of you may be wondering why I did not derive from ContextBoundObject and use interception to hijack the call coming into the method so that I could perform the validation before the function body actually got executed? I actually thought long and hard about this solution, but I ultimately decided against it.

For those out there who don’t know what the ContextBoundObject is. It is derived from MarshalByRef and it enables you to intercept calls to your method in order to perform some action (such as validation). For more information on ContextBoundObject, see the definition of ContextBoundObject on MSDN

The rationale for me was simple. ContextBoundObject is derived from MarshalByRef and I did not want to force someone to implement MarshalByRef to use this code. Secondly, there are many rumors that Microsoft will be deprecating this class and a new implementation is forthcoming with the Whidbey release in 2005.

What about Code Injection?

Should I inject my validation code at the top of a function body during compilation? In other words, say I come up with the attribute type called “Inject” that when decorated on a Method or Constructor informs some add-in that I write to inject the necessary code at the top of every method for performing validation. I actually like this idea a lot. The developer would have to choose to have code injected by decorating a method or constructor with this special attribute type. Second, it completely removes the clutter from client code. The downside is that it will probably mean a visual studio add-in or some additional compilation step. These approaches may require additional rework to make them work with Borland’s C# Builder and Mono.


Summary

This article stressed the importance of creating and leveraging a Validation scheme to protect your system from invalid data. The article also demonstrated that Attributes are useful for assigning Meta information to pieces of your design, but that they are not useful by themselves. You must reflect upon them and then act upon them to make them useful. Furthermore, the article demonstrated how you can use custom attribute programming, reflection and formatting to create a design that offers the flexibility needed for a robust and flexible solution.

A complete listing of this code can be found at http://www.cybral.com/solutions/tools.htm

What Next

Validation is something that can and should continue to grow in practice and in application. If, after reading this article, you have constructive feedback please email me at mnolton@cybral.com. I am looking for input into how to evolve this framework. Or visit my website at www.cybral.com. I hope to provide a means to post comments about this framework there soon.