Being Bad
One of the primary reasons for application errors (and the often-disastrous consequences that follow) is the “bad” data entered by the application’s end-users. It’s not uncommon to find applications falling apart because the user made a mistake while entering a critical piece of information…especially if the application’s been written by a novice developer too inexperienced to know better.
If that novice developer is you, you’re going to thank your stars that you found this article today.
Now, you can’t stop a user from entering bad data into your application - but you can certainly check what’s been entered and trigger off warnings if it’s incorrect. This process is called input validation, and it’s something you must do in every application you develop. This is twice as true for Web applications, which involve lots of forms and databases - if you don’t have input validation in your Web-based application, you run the risk of corrupting your database by allowing incorrect, unverified values to be stored in it.
Over the next few pages, I’m going to show you how you can wrap your code in bulletproof Kevlar, so that no matter how bad the user input is, your code detects it, warns the user about it, and keeps ticking instead of blowing all its fuses. In ASP.NET, doing this is surprisingly simple…if you know about the built-in Validators.
Making Friends
It is a common practice to use client-side scripting languages like JavaScript or VBScript for client side input validation. However, this type of client-side validation is not foolproof - remember, you’re not in control of the client, so if a user turns off JavaScript in his or her browser, all your efforts to ensure that the user does not enter irrelevant data will become…well, irrelevant. That’s why most experienced developers use both client-side and server-side validation. Server-side validation involves checking the values submitted to the server through a server-side script, and taking appropriate action when the input is incorrect.
That’s where the ASP.NET Validator controls come in. In a Web-based application, each Validator control (there are five of them in all, and I’ve covered them all in this tutorial) is linked to a form control. When a user submits a form, the .NET framework ensures that the data entered by the user is filtered through the Validators, and checked for accuracy. If any of the values flunk the validation tests, an exception is generated; this can then be caught and resolved by the application’s exception-handling mechanisms.
With ASP.NET’s Validators, it’s also possible to perform selective validation, wherein one validation test is dependent on the results of another. For example, if the user states that (s)he’s living in the US, you might also require him or her to enter a US state code. However, if the user indicates that (s)he’s living outside the US, it doesn’t make sense to ask for a state code.
So which kinds of validations are possible using these ASP.NET Validator controls? Here’s a quick list:
-
RequiredFieldValidator - forces entry of a value for the associated control
-
CompareValidator - used with a comparison operator to compare the value provided against a constant value or another control
-
RangeValidator - checks whether the value entered is within a specified range
-
RegularExpressionValidator - uses regular expressions to validate user input
-
CustomValidator - allows you to create customized validation routines
First Glance
Enough theory. Let’s get our hands dirty with some code, shall we?
<%@ Page Language="C#" %>
<html>
<head>
<title>What's In A Name?</title>
<basefont face="Arial">
</head>
<body>
<form runat="server" method="POST" >
<asp:label id="lblFirstName" runat="server" text="Your name, please? " /> <asp:textbox id="strFirstName" runat="server"/>
<br />
<asp:RequiredFieldValidator id="strFirstNameRFV" ControlToValidate="strFirstName" ErrorMessage="Don't you have a name?" runat="server"/>
<br />
<asp:button id="Submit" Text="Submit" runat="server"/>
</form>
</body>
</html>
In case you see errors about a missing “WebUIValidation.js” file instead of the form above, ensure that this file is under your Web server root, in the “\aspnet_client\system_web\1_1_4322” folder (you can locate the file by doing a quick search on your .NET development system), and then try again.
Now, submit the form without entering any data, and you should now see an error message on the screen.
There’s nothing very exciting about the code above - the first few lines simply make use of two plain-vanilla server controls, a label and a textbox; the latter allows the user to enter his/her name. The meat of the script lies in this line:
<asp:RequiredFieldValidator id="strFirstNameRFV" ControlToValidate="strFirstName" ErrorMessage="Don't you have a name?" runat="server"/>
This is your very first ASP.NET Validator control. Aptly called the RequiredFieldValidator control, it forces the user to enter a value in the associated field. Here are the attributes I’ve used:
-
The “id” attribute specifies a unique identifier for this control (useful if you want to script actions based on the state of this object).
-
The “ControlToValidate” attribute associates this control with a form field. Since I want to validate the “strFirstName” textbox control, I’ve assigned it this value.
-
The “ErrorMessage” attribute stores the message to be displayed to the user, if (s)he does not enter a value in the “strFirstName” textbox control.
-
The mandatory “runat=server” attribute tells the .NET CLR that this control has to be processed at the server and not the client.
Now, you might be wondering whether the client or the server performed the validation. Take a guess!
And if you guessed “the client”, you guessed right! However, note that this doesn’t mean that server-side validation is disabled; if, for some reason, client-side validation fails, the server will leap in and enforce your validations instead. Flip the page, and I’ll tell you a little more.
If Looks Could Kill
In the previous example, I allowed the client to carry out input validation first. However, at times, you may want to shift this responsibility directly to the server. ASP.NET allows you to do this, simply by adding an additional attribute to your RequiredFieldValidator definition.
<%@ Page Language="C#" %>
<html>
<head>
<title>What's in a name</title>
<basefont face="Arial">
</head>
<body>
<form runat="server" method="POST" >
<asp:label id="lblFirstName" runat="server" text="Your name, please? " /> <asp:textbox id="strFirstName" runat="server"/>
<asp:RequiredFieldValidator id="strFirstNameRFV" ControlToValidate="strFirstName" ErrorMessage="Don't you have a name?" runat="server" EnableClientScript="false" ForeColor="#FF0000" BackColor="#CCCCCC" BorderWidth="2" BorderColor="#000000" Display="dynamic" Style="font-family:verdana;padding: 3px;font-weight:bold;font-size:10px" />
<asp:button id="Submit" Text="Submit" runat="server"/>
</form>
</body>
</html>
I’m sure you’re wondering why the number of attributes for the RequiredFieldValidator control has suddenly increased. A close inspection will reveal that most of these are responsible for the formatting of the error message. However, the first and most important change is the “EnableClientScript” attribute, a simple flag that can be set to “true” or “false”, depending on whether or not you wish to carry out client-side validation. Set this to “true” (the default value) and all validations will be carried out on the client; set it to “false” and the server will take over the responsibility for input validation
Next, we have the “Display” attribute”. This is an interesting attribute, useful if you want to ensure that the error messages generated by the Validator do not destroy the design and layout of your Web pages. If this value is set to “dynamic”, the area where the error message appears is hidden till such time as the error message is to be displayed
Finally, I have a list of attributes to control the display of the error message:
-
The “ForeColor” attribute controls the color used to display the error message
-
The “BackColor” attribute controls the background color for the area displaying the error message
-
The “BorderWidth” attribute controls the width of the border for the area displaying the message
-
The “BorderColor” attribute controls the color of the border around the message
-The “Style” attribute allows you to specify CSS properties for the text of the error message
Pizza Power
So far, I have demonstrated the RequiredFieldValidator validation control. Now, take a look at this next example, which introduces the next member of the ASP.NET Validator family:
<%@ Page Language="C#" %>
<html>
<head>
<title>Great Pizza Offer</title>
<basefont face="Arial">
</style>
</head>
<body>
<h2>The Great Pizza Offer</h2>
<form runat="server" method="POST" >
<asp:label id="lblPizzaName" runat="server" text="Which Pizza?" />
<asp:textbox id="strPizzaName" runat="server"/>
<asp:RequiredFieldValidator id="strPizzaNameRFV" ControlToValidate="strPizzaName" ErrorMessage="You need to tell me which pizza you want!" runat="server" Display="dynamic" />
<p> </p>
<asp:label id="lblPizzaQuantity" runat="server" text="How many?" />
<asp:textbox id="strPizzaQuantity" runat="server" />
<asp:RequiredFieldValidator id="strPizzaQuantityRFV" ControlToValidate="strPizzaQuantity" ErrorMessage="You need to tell me how many you want!" runat="server" Display="dynamic" />
<asp:RangeValidator id="strPizzaQuantityRV" ControlToValidate="strPizzaQuantity" ErrorMessage="You can select a maximum of three pizzas under this offer!" Type="Integer" MinimumValue="1" MaximumValue="3" runat="server" Display="dynamic"/>
<p>
<asp:button id="Submit" Text="Order" runat="server"/>
</form>
</body>
</html>
Hit the “Order” button without filling up the form correctly, and a whole bunch of error messages will be thrown back at you.
Let’s look at how I managed this feat:
<%
<asp:label id="lblPizzaName" runat="server" text="Which Pizza?" />
<asp:textbox id="strPizzaName" runat="server"/>
<asp:RequiredFieldValidator id="strPizzaNameRFV" ControlToValidate="strPizzaName" ErrorMessage="You need to tell me which pizza you want!" runat="server" Display="dynamic" />
%>
Nothing new here - I’ve used the RequiredFieldValidator control again to ensure that the user enters the name of the pizza (s)he wishes to order.
<%
<asp:label id="lblPizzaQuantity" runat="server" text="How many?" />
<asp:textbox id="strPizzaQuantity" runat="server" />
<asp:RequiredFieldValidator id="strPizzaQuantityRFV" ControlToValidate="strPizzaQuantity" ErrorMessage="You need to tell me how many you want!" runat="server" Display="dynamic" />
<asp:RangeValidator id="strPizzaQuantityRV" ControlToValidate="strPizzaQuantity" ErrorMessage="You can select a maximum of three pizzas under this offer!" Type="Integer" MinimumValue="1" MaximumValue="3" runat="server" Display="dynamic"/>
%>
Now, here’s something new - a RangeValidator control. As noted earlier, this allows you to specify a range of valid values for the ASP.NET control it is associated with. You’ve already seen what the “id”, “ControlToValidate” and “ErrorMessage” attributes do; the RangeValidator control adds three new ones, “Type”, “MinimumValue” and “MaximumValue”, that allow you to specify the datatype and boundary entries for the range of allowed values. In this case, the RangeValidator control will force the user to enter a number between 1 and 3.
One more interesting thing about the example above: ASP.NET allows you to easily associate two Validator controls with the same server control. For example, in the example above, I have applied the RequiredFieldValidator and the RangeValidator controls to the same “strPizzaQuantity” text box control. The first forces the user to enter some value in the field; the second sets the allowed values for the field. This capability means that you can easily use a set of validation controls to enforce complex business rules.
A Comparative Study
Next up, comparing values with each other. ASP.NET comes with a very cool CompareValidator control, which lets you compare the value of a control with a constant value or that of another control. Consider the following example, which illustrates:
<%@ Page Language="C#" %>
<html>
<head>
<basefont face="Arial">
</head>
<body>
<form runat="server" method="POST" >
<asp:label id="lblPassword1" runat="server" text="Your Password?" /> <asp:textbox id="strPassword1" runat="server" />
<p>
<asp:label id="lblPassword2" runat="server" text="Please re-enter" /> <asp:textbox id="strPassword2" runat="server" />
<p>
<asp:CompareValidator id="strPasswordCV" ControlToValidate="strPassword2" ErrorMessage="Please re-enter your password correctly!" ControlToCompare="strPassword1" runat="server" />
<p>
<asp:button id="Submit" Text="Order" runat="server"/>
</form>
</body>
</html>
All the magic here happens with the CompareValidator control. Here are the important lines:
<%
<asp:label id="lblPassword1" runat="server" text="Your Password?" /> <asp:textbox id="strPassword1" runat="server" />
<asp:label id="lblPassword2" runat="server" text="Please re-enter" /> <asp:textbox id="strPassword2" runat="server" />
<asp:CompareValidator id="strPasswordCV" ControlToValidate="strPassword2" ErrorMessage="Please re-enter your password correctly!" ControlToCompare="strPassword1" runat="server" />
%>
Apart from the standard “ControlToValidate” and “ErrorMessage” attributes, the CompareValidator control comes with a “ValueToCompare” attribute - this is used to specify a constant value against which the value entered by the user will be compared. It’s pretty easy to understand, once you know what to look for.
And that’s about it for this first segment. I started this article with a brief introduction to the importance of input validation, especially in the context of a Web-based application, and a quick overview of the types of validation controls built into ASP.NET. This was followed by an introduction to the RequiredFieldValidator control, used to force input into a specific form field. The wide range of attributes accompanying this (and other) Validator controls allows you to control the display and formatting of the error messages; these attributes were discussed at length, together with an illustration of a truly hideous error message.
With the basics out of the way, I moved on to the RangeValidator control, showing you how it can be used to restrict the datatype and allowed range of values for a field. I also showed you the CompareValidator control, which allows you to compare the value of the target control with a static value or another server control on the page, and illustrated it with a very common Web application - password reconfirmation.
In the second, and concluding, segment of this tutorial, I’ll be explaining how you can perform more sophisticated input validation, with the remaining two Validator controls, the RegularExpressionValidator control and the CustomValidator control. These two controls are not as simple as the ones you’ve just seen, so you’ll need to have all your wits about you when we start in on them. Additionally, I’ll also demonstrate how you can display a summary of input validation errors to the user instead of displaying errors as they occur on a per-control basis.
Until next time…be good, and keep practicing!
Note: Examples are illustrative only, and are not meant for a production environment. Melonfire provides no warranties or support for the source code described in this article. YMMV!
This article was first published on 18 Dec 2003.