
March 23, 2004
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:
- RequiredFieldValidator – Makes the associated input control a required
field.
- CompareValidator – Compares the value entered by the user into an
input control with the value entered into another input control or a constant
value.
- RangeValidator – Checks whether the value of an input control is
within a specified range of values.
- RegularExpressionValidator – Validates whether the value of an associated
input control matches the pattern specified by a regular expression.
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:
- Commands/Behaviors. And
- The Validation Process
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:
- Call Validate(). This method will throw a ValidationException listing all
errors encountered. Or
- Access the collection of errors via the DetailMessages property. If there
are no errors, the collection will have a count of 0. And/Or
- 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
- 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.
Authors
 | Mathew Nolton is a software architect in Atlanta. Through his company Cybral (www.cybral.com), he focuses on designing and deploying N-Tier application and web service architectures on the .Net platform.
|
|