This code sample applies to Asp.Net for the .NET 2.0 framework. Examples are written in C#. 
Contents
- The Problem
- The Approach
- Server Side Validation Library Overview
- Example One
- Example Two
- Conclusion
The Problem:
In my coding I've shied away from using the Validation Controls as I've found them to fall prey to that most ubitiquous of all rules: The 80/20 Rule. For the 80% of cases like validating a "First Name" field, they work great. Clients love the coolness factor of the immediate feedback and the code required to use them is minimal. When it comes to the other 20% of cases, like when I need to ensure that the value entered for an accout is less than $10,000 if the client is using "Student Checking" and has had the account for less than 3 years, it is a different story. These cases often require writing complex javascript, adopting a hybrid client-side/server-side approach, or dropping client-side validation altogether. Since the 20% case will occur 100% of the time, I view server side validation as a better approach except in those (few) instances where avoiding a roundtrip to the server is REALLY important.
The Approach:
This article will introduce you to a server side validation library. The objectives of the library are to:
- Provide a uniform and extensible approach for even complex validation scenarios.
- Reduce the amount of code required for user input validation.
- Create a consistent user experience with both visual and textual feedback regarding specific user input errors.
- Centralize page-level user validation so that it is easier to maintain and comprehend.
Server Side Validation Library Overview

Figure 1: Class Diagram
A note for those familar with the CSLA framework by Rockford Lhotka, you will notice the similarity regarding the "BrokenRules" name. This is about the only similarity between what is offerred here and Lhotka's framework. I did read and enjoy Lhotka's Expert C# 2005 Business Objects, so perhaps like Kaavya Viswanathan I was unconsciously influenced in my choice of class names...
Below is a simple description of each of the main classes and their role in the library --it is not meant to be exhaustive, but simply to give a quick overview.
BrokenRules and BrokenWebRules: These are principal classes in the library. BrokenWebRules in particular forms the backbone of the library as it contains the methods you will use to evaluate certain rules --e.g., Required, Assert, AssertPattern, etc.
BrokenRule: A Struct containing information about a particular validation rule.
StyleItem, ClassStyle, and InlineStyle: Information about the particular style to apply to invalid (or valid) controls. The BrokenWebRules uses the Strategy Pattern to determine how to change the style or class of a control.
StyleItemCollection: A collection to hold the various styles that should be applied to invalid (or valid) controls. This is used by the BrokenWebRule to apply the styles when a rule is called.
Example One
Take the form to the right. In this cases we want to make sure that all the fields marked with an * are not empty. In addition, if the user selects "Other" from the drop down list as their favorite movie we want to ensure that they complete the textbox associated with that field.

Image 1: Sample Form
If the user clicks submit without completing the required fields, the result is shown to the right. The invalid fields are displayed with a red border and the background is rendered light grey. The respective labels text is displayed in bold red. By hovering your mouse over either the label or field a tooltip is displayed indicating the reason the field is invalid.
Image 2: Sample Invalid Form
As the example code below will (I hope) show the application of the Server Side Validation Library is fairly straight forward. When the Submit button is clicked its event handler calls the ApplyRules method. This method in turn calls SetStyles which creates an instance of StyleItemCollection and various styles are assigned to the respective control types --by not passing in a Type to the AddInlineStyle method that style will apply to all HtmlControl and WebControl types. The StyleItemCollection is then returned back and passed into the newly created instance of BrokenWebRules. This informs BrokenWebRules of what styles to apply if a rule is invalid and to what control type. BrokenWebRules then successively applies each of the rules --e.g., the Required and Assert calls-- to the specified fields. Finally, whether or not any rule was broken is returned to the event handler which continues to process the event. (Click on the View Code header to follow the logic. Both the aspx and code behind are included.)
Click to View the Code
The Sample Form Aspx Page:
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
runat
="server"
>
<
title
>
CoreWeb.Com
</
title
>
<
link
id
="lnkCss"
runat
="server"
rel
="stylesheet"
href
="~/Base.css"
/>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
style
="margin: 10px;"
>
<
h2
>
Sample Form
</
h2
>
<
table
>
<
tr
>
<
td
><
asp:Label
id
="lblFirstName"
runat
="server"
Text
="First Name <span class='required'>*</span>"
/>
</
td
>
<
td
><
asp:TextBox
id
="tbFirstName"
runat
="server"
/>
</
td
>
</
tr
>
<
tr
>
<
td
><
asp:Label
id
="lblLastName"
runat
="server"
Text
="Last Name <span class='required'>*</span>"
/>
</
td
>
<
td
><
asp:TextBox
id
="tbLastName"
runat
="server"
/>
</
td
>
</
tr
>
<
tr
>
<
td
><
asp:Label
id
="lblFavoriteMovie"
runat
="server"
Text
="Favorite Movie <span class='required'>*</span>"
/>
</
td
>
<
td
>
<
asp:DropDownList
id
="ddlFavoriteMovie"
runat
="server"
>
<
asp:ListItem
Text
="Space Mutiny"
/>
<
asp:ListItem
Text
="Beaches"
/>
<
asp:ListItem
Text
="Other"
/>
</
asp:DropDownList
>
<
asp:Label
id
="lblFavoriteMovieOther"
runat
="server"
Text
="Other: "
/>
<
asp:TextBox
id
="tbFavoriteMovie"
runat
="server"
/>
</
td
>
</
tr
>
<
tr
>
<
td
colspan
="2"
style
="padding: 5px; text-align:right;"
>
<
asp:Button
id
="btnSubmit"
runat
="server"
Text
="Submit"
/>
</
td
>
</
tr
>
</
table
>
</
div
>
</
form
>
</
body
>
</
html
>
The Sample Form Aspx.CS Page:
using
System;
using
System.Data;
using
System.Configuration;
using
System.Collections;
using
System.Web;
using
System.Web.Security;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.Web.UI.WebControls.WebParts;
using
System.Web.UI.HtmlControls;
using
CoreWebLibrary.Validation.BrokenRules;
public
partial
class
Demos_Article4_FormDemo : System.Web.UI.Page {
protected
void
Page_Load(
object
sender, EventArgs e) { RegisterEvents(); }
private
void
RegisterEvents() { btnSubmit.Click
+=
new
EventHandler(OnSubmitClick); }
private
BrokenRulesStyleCollection SetStyles() {
//
Set up the styles. Likely this would be done
//
in a BasePage or some other
//
central location.
BrokenRulesStyleCollection brokenRulesStyles
=
new
BrokenRulesStyleCollection();
//
These styles will only apply to controls of
//
Type System.Web.UI.WebControls.Label
brokenRulesStyles.AddInlineStyle(
"
color
"
,
"
red
"
, lblFirstName.GetType()); brokenRulesStyles.AddInlineStyle(
"
font-weight
"
,
"
bold
"
, lblFirstName.GetType());
//
These styles will only apply to controls of
//
Type System.Web.UI.WebControls.TextBox
//
or System.Web.UI.WebControls.DropDownList
brokenRulesStyles.AddInlineStyle(
"
border
"
,
"
solid 1px red
"
, tbFirstName.GetType(), ddlFavoriteMovie.GetType()); brokenRulesStyles.AddInlineStyle(
"
background-color
"
,
"
#eeeeee
"
, tbFirstName.GetType(), ddlFavoriteMovie.GetType());
return
brokenRulesStyles ; }
private
bool
ApplyRules() {
//
Pass in the style object to the BrokenWebRules
//
class. This tells it how to modify the
//
controls in the event that a rule is violated.
BrokenWebRules brokenRules
=
new
BrokenWebRules( SetStyles() );
//
Set up the various rules for the page.
//
The second, (Name argument), must be
//
unique. It is how the rule is identified.
brokenRules.Required(tbFirstName.Text,
"
First Name
"
,
"
First Name is required
"
, lblFirstName, tbFirstName); brokenRules.Required(tbLastName.Text,
"
Last Name
"
,
"
Last Name is required
"
, lblLastName, tbLastName); brokenRules.Required(ddlFavoriteMovie.SelectedItem.Text,
"
Favorite Movie
"
,
"
Favorite Movie is required
"
, lblFavoriteMovie, ddlFavoriteMovie); brokenRules.Assert(ddlFavoriteMovie.SelectedValue
!=
"
Other
"
||
tbFavoriteMovie.Text.Length
>
0
,
"
Other Movie
"
,
"
You must include your favorite movie if Other was selected
"
, lblFavoriteMovieOther, tbFavoriteMovie);
//
Return if false is any rule was broken, true otherwise.
return
brokenRules.IsValid; }
private
void
OnSubmitClick(
object
sender, EventArgs e) {
//
Check to make sure the form is valid
bool
isValid
=
ApplyRules();
if
( isValid ) {
//
The form is valid so do something
}
else
{
//
The form is invalid so do something else
} } }
Example Two:
Example Two is a slight twist on the first example. In this case we are using classes defined in the applications linked CSS file to do the formatting and rather than just check to see if the "First Name" field is complete we are checking to ensure that it conforms to a Regular Expression pattern -- that First Name only contains alphabetical characters. To simplify the presentation, I've only included the SetStyles and ApplyRules method since that is the only part that changed.
Click to View the Code
The Sample Form Aspx Page:
private
BrokenRulesStyleCollection SetStyles() {
//
Set up the styles. Likely this would be done in a
//
BasePage or some other central location.
BrokenRulesStyleCollection brokenRulesStyles
=
new
BrokenRulesStyleCollection();
//
This class will only apply to controls
//
of Type System.Web.UI.WebControls.Label
brokenRulesStyles.AddCssStyle(
"
normalLabel
"
,
"
errorLabel
"
, lblFirstName.GetType());
//
This class will only apply to controls of
//
Type System.Web.UI.WebControls.TextBox or
//
System.Web.UI.WebControls.DropDownList
brokenRulesStyles.AddCssStyle(
"
normalControl
"
,
"
errorControl
"
, tbFirstName.GetType(), ddlFavoriteMovie.GetType());
return
brokenRulesStyles ; }
private
bool
ApplyRules() { BrokenWebRules brokenRules
=
new
BrokenWebRules(SetStyles());
//
checking for the pattern.
brokenRules.AssertPattern(
"
^[a-zA-Z]+$
"
, tbFirstName.Text,
"
First Name
"
,
"
First Name can only contain alphabetical characters
"
, lblFirstName, tbFirstName); brokenRules.Required(tbLastName.Text,
"
Last Name
"
,
"
Last Name is required
"
, lblLastName, tbLastName); brokenRules.Required(ddlFavoriteMovie.SelectedItem.Text,
"
Favorite Movie
"
,
"
Favorite Movie is required
"
, lblFavoriteMovie, ddlFavoriteMovie); brokenRules.Assert(ddlFavoriteMovie.SelectedValue
!=
"
Other
"
||
tbFavoriteMovie.Text.Length
>
0
,
"
Other Movie
"
,
"
You must include your favorite movie if Other was selected
"
, lblFavoriteMovieOther, tbFavoriteMovie);
return
brokenRules.IsValid; }
Conclusion
I hope that you found this helpful and that the BrokenRules Server Side Validation Library will simplify your validation needs. I look foward to your comments and if you extend the library, please send me what you've done.