ControlFreak
LANGUAGES:
VB.NET
ASP.NET
VERSIONS: 1.x | 2.0
Validate User-entered Data
Protect Your Database from Invalid Data by Using the Built-in
ASP.NET Validation Controls
By Steve C. Orr
If you haven t familiarized yourself with the validation
controls in ASP.NET, it s time to learn. The functionality is far too powerful
to ignore. If you let people enter three-digit ZIP codes, two-digit phone
numbers, and other such nonsense, then over time your database will become
cluttered with garbage beyond all hope of repair. It s sad to see a perfectly
good application go down in such a needlessly gruesome way. It doesn t have to
be like that. These controls are a snap to use and will take care of nearly all
your data validation needs with little effort on your part.
Make Important Fields Mandatory
One of the most basic validation situations you ll run
across is to ensure the user has filled in all required values. A billing
address without a city or ZIP code simply isn t useful. The
RequiredFieldValidator Web control is what you need for a situation such as
this. It, like the rest of the validation controls mentioned in this article,
comes standard with Visual Studio.NET, and can be found in the Web Forms
section of your toolbox.
A typical RequiredFieldValidator control is defined in an
ASPX file with a definition similar to this:
<asp:RequiredFieldValidator
id="RequiredFieldValidator1"
runat="server"
ErrorMessage="This field is required!"
ControlToValidate="TextBox1"></asp:RequiredFieldValidator>
To see such a control in action, simply start a new Web
application in Visual Studio.NET and drag a textbox, a RequiredFieldValidator
control, and a button onto your Web Form. Set the ControlToValidate property of
the RequiredFieldValidator control to the name of the textbox (TextBox1 by
default). Now run the project and click on the button without typing anything
in the textbox. You ll notice that the RequiredFieldValidator control springs
into action and prevents the postback from occurring and displays a red error
message. The default message is not friendly, so you should stop the
application and improve the message by changing the ErrorMessage property of
the RequiredFieldValidator control to more appropriate text.
Preventing the postback from occurring when there s
invalid data is an efficient use of client-side script. This client-side script
is generated automatically, so you might never even notice it s there. However,
not all browsers support client-side script, and some users may have it
disabled as a security precaution. Therefore, server-side validation is also
done (automatically) as a failsafe.
Now things work pretty nicely. The user gets a friendly
notification when they fail to enter an important value that is required by
your application. The only details left are really a matter of polish, and such
details can be the difference between an application that merely works, and one
that impresses people.
Before the user has clicked the button, there is no
indication that the field is required. Sure, they ll be notified after they hit
the button, but this can waste precious seconds of the user s time. A standard
solution is to display an asterisk (*) next to the field, or some other label
to visually identify the field as required. To do this, you only need to set
the Text property of the RequiredFieldValidator control.
Another notable property of the RequiredFieldValidator
control is InitialValue. This allows you to place some text into the control to
be validated, and have it be recognized by the validator control as a non-user-entered
value. This tends to be useful in situations where screen real estate is
cramped and precious, and you d rather not put an identifying label next to the
control. Figure 1 illustrates this situation. This technique also works great
with DropDownLists, so that you can select a default Choose from below item
and still ensure the user selects an item from the list.
Figure 1: The InitialValue property
of the RequiredFieldValidator control lets you define an initial message in the
control without setting off the validation error message.
Tip: Imagine for a moment that you have another unrelated
button on the Web form, perhaps a Help button. You probably don t want this
button click event to be prevented by invalid data. Therefore, you should set
the CausesValidation property of the Help button to false. Now the user can get
help at any time, whether they ve entered valid data yet or not.
Field Comparison
Sometimes you need to compare two fields to each other to
ensure validity. Sometimes the values need to match. Sometimes you need to make
sure they re different from each other. Sometimes you need to make sure one
value is greater than the other, and so on. The CompareValidator is an ideal
tool for handling these kinds of validation.
One common example is a new user registration page. The
user needs to type in their new password, and then they need to type it again
to confirm they know their password and typed it correctly. In this case, both
password fields must match or else the data is considered to be in an invalid
state. Such a page is illustrated in Figure 2.
Figure 2: This Web form shows all six
validation controls in action: RequiredFieldValidator, CompareValidator,
RangeValidator, RegularExpressionValidator, CustomValidator, and
ValidationSummary.
This control (like all the validation controls) has a
ControlToValidate property that specifies the primary validation field on the Web
form. The CompareValidator control also has a ControlToCompare property that
specifies a second control to which the ControlToValidate field can be
compared. If you wish to compare the control to a value that is not present in
another control on the form, you should use the ValueToCompare property instead
of the ControlToCompare property:
<asp:CompareValidator id="CompareValidator1"
runat="server"
ControlToValidate="txtPassword1"
ControlToCompare="txtPassword2"
Operator="Equal"
ErrorMessage="Passwords
don't match"></asp:CompareValidator>
Another unique property of this control is the Operator
property. It specifies what kind of comparison will be done between the two
controls. A value of Equal specifies that the values of the two controls must
be identical. The other possible values are: NotEqual, GreaterThan,
GreaterThanEqual, LessThan, LessThanEqual, and DataTypeCheck. They are all
fairly self-explanatory, except perhaps DataTypeCheck. When this is selected,
it is used in conjunction with the Type property, which can contain values of
String, Integer, Double, Date, or Currency. If the value in the
ControlToValidate field cannot be converted to the chosen data type, then it is
considered invalid and the value of the ErrorMessage property will be displayed
to the user.
Accept Data within a Specified Range
It is often necessary to ensure a user-entered value is
within a reasonable range. For example, if somebody claims to be 574 years old,
then you can be fairly certain they ve made a mistake. The RangeValidator
control comes into play for just this type of situation. It has a MinimumValue
property and a MaximumValue property to specify the lower and upper bounds of
acceptable values:
<asp:RangeValidator id="RangeValidator1"
runat="server"
ControlToValidate="TextBox1"
ErrorMessage="Invalid Age"
MinimumValue="18"
MaximumValue="120" Type="Integer">
</asp:RangeValidator>
The RangeValidator control has a Type property that can
contain values of String, Integer, Double, Date, or Currency. This property is
important because it specifies how the data will be interpreted. The value that
the user entered, along with the MinimumValue and MaximumValue properties, are
all converted to this data type before they are compared. (If they cannot be
converted to the specified data type, the data is considered invalid and the
ErrorMessage text will be displayed.)
If you set the MaximumValue field to 120 and the
MinimumValue field to 18 and ignore the Type property, the control will throw a
compile-time error specifying that the MaximumValue property must be greater
than the MinimumValue property. But 120 is greater than 18! you ll say. Ahh,
when they are compared as numbers this is true, but you forgot to set the Type
property to Integer and left it at the default of String. The string 18 is
indeed greater than the string 120 , thus causing the potentially confusing
error.
Validate with Regular Expressions
When your data needs to get a bit more complex, you need
to break out some new tricks. Although there is no masked edit control built
into ASP.NET 1.x, the RegularExpressionValidator is the next best thing. Regular
Expressions are a way to describe a string pattern, such as an e-mail address. There
are many ways to incorrectly type an e-mail address, so regular expressions are
the most efficient way to make sure all your bases are covered. The RegularExpressionValidator
control has a ValidationExpression property that holds the regular expression
that will be compared against the value the user enters into the
ControlToValidate control. In the Visual Studio.NET property window for the
RegularExpressionValidator control you ll find an ellipsis (...) button in the
ValidationExpression property. Click the button to choose from a list of the
most common regular expressions, which contains values for phone numbers, e-mail
addresses, Social Security numbers, ZIP codes, and more. If you don t find the
expression you need, I suggest you look for the one you need at http://www.regexplib.com.
You can of course design your own custom regular
expressions to match any string pattern you can imagine, although it might be
quite a learning experience if you re not already familiar with regular
expressions:
<asp:RegularExpressionValidator
id="RegularExpressionValidator1"
runat="server"
ControlToValidate="TextBox1"
ValidationExpression="\d{5}(\d{4})?"
ErrorMessage="Invalid
Zip Code!">
</asp:RegularExpressionValidator>
It s a deep topic. There are entire books written on the
subject.
Create Custom Validators
I suspect you agree by now that the validation controls
are quite easy to use. Have you noticed all the power that has been described
so far without a single line of code needing to be written? Well, automatic
features like these are nice, but there will always be times when you need to
take control of the helm and write some custom code. Although the previously
explained controls should be able to handle 95% of your validation needs, the
CustomValidator control takes care of the rest:
<asp:CustomValidator id="CustomValidator1"
runat="server"
ErrorMessage="Invalid
Password"
ControlToValidate="TextBox1"></asp:CustomValidator>
The only unique property of this control is named
ClientValidationFunction. As you might suspect, this property is meant to hold
the name of a custom client-side function that will handle client-side
validation. This property is optional, and client-side validation can be turned
off for any of the validation controls by setting the EnableClientScript
property to false. The function shown in Figure 3 is an example of a client-side
function that validates the number a person entered is an even number.
<script language="vbscript">
<!--
Sub
ClientValidate(source, arguments)
If arguments.Value/2 =
CInt(arguments.Value/2) Then
arguments.IsValid=true
Else
arguments.IsValid=false
End If
End Sub
' -->
</script>
Figure 3: Using
the CustomValidator control to call your own client-side validation functions
such as this is more efficient than relying on server-side validation alone.
You should always implement server-side validation (just
like the other validation controls do automatically) to be sure validation
happens, even if client-side script is not enabled. For this reason, the
CustomValidator control has a server-side event named ServerValidate. Figure 4
contains a server-side validation routine that matches the client-side
validation routine shown in Figure 3.
'VB.NET
Private Sub CustomValidator1_ServerValidate(ByVal source _
As System.Object, ByVal args _
As System.Web.UI.WebControls.ServerValidateEventArgs) _
Handles CustomValidator1.ServerValidate
If args.Value / 2 =
CInt(args.Value / 2) Then
args.IsValid = True
Else
args.IsValid =
False
End If
End Sub
Figure 4: Don t
forget to implement a server-side validation function for the CustomValidator
control, because client-side validation alone is not very dependable.
Summarizing Validation Errors
The ValidationSummary control is unlike the other
validation controls because it doesn t actually do any validation. Rather, it s
more of a list that can sum up all the validation errors on the page and
display them in one place. Alternatively, you can have it pop up a message box
detailing the various errors. The corresponding Boolean properties of the
control are named ShowSummary and ShowMessageBox:
<asp:ValidationSummary id="ValidationSummary1"
runat="server"
Width="184px" HeaderText="Error Summary:"
BorderStyle="Dotted"
ShowMessageBox="True">
</asp:ValidationSummary>
If you ve got a complex data entry form that has room for
many errors, the ValidationSummary control can be a valuable way to communicate
with the user about what exactly they ve done wrong as compared with your
expectations. You can see it in action at the right side of Figure 2. The
output is a bit ugly by default, but you can adjust many visual properties to
make it more attractive.
Visions of the Future
The worst limitation about the validation controls in
ASP.NET 1.x is that you can only validate one group of controls on a page. For
example, maybe you ve got a standard newsletter sign-up textbox in the left
margin of every page and you want to validate the e-mail address they enter
(perhaps using the RegularExpressionValidator control). Then, in the middle of
one of your pages, you ve got some input fields (shipping address fields, for
example) that are required (using the RequiredFieldValidator control). The user
enters their e-mail address to sign up for your newsletter and clicks the
submit button next to it, and they are wrongly halted because they didn t fill
in the completely unrelated shipping address fields.
In ASP.NET 1.x there just isn t a graceful solution for a
conundrum such as this. Luckily, they ve fixed this annoying problem in ASP.NET
2.0 by implementing Validation Groups. Figure 5 illustrates the solution s
syntax. It defines two standard textboxes, a validator for each, and a button
for each. Because the first validator is defined as belonging to Group1, and
the first button is also assigned Group1, only the first validator is executed
when Group1 s button is clicked. Likewise, only Group2 s validator(s) will be
fired when Group 2 s button is clicked.
<asp:textbox id="Email" runat="server"/>
<asp:textbox id="ShippingAddress"
runat="server"/>
<asp:RegularExpressionValidator
ValidationGroup="Group1"
id="RegularExpressionValidator1"
runat="server"
ErrorMessage="Invalid Email Address"
ControlToValidate="txtEmail" ValidationExpression=
"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">
</asp:RegularExpressionValidator></P>
<asp:requiredfieldvalidator ValidationGroup="Group2"
ErrorText="Need to
Fill in Value! "
ControlToValidate="ShippingAddress"
runat="server"/>
<asp:button text="Group1"
ValidationGroup="Group1"
runat="server"/>
<asp:button text="Group2"
ValidationGroup="Group2"
runat="server"/>
Figure 5: Validation
Groups in ASP.NET 2.0 will solve the frustrating dilemma of having unrelated
sets of controls interfere with each other s validation.
Tidbits
If needed, you can mix and match controls to (for example)
mark a field as required AND verify it s within a specified range. For this
scenario, simply use two validation controls (the RequiredFieldValidator and
the RangeValidator) and give them both the same ControlToValidate.
The Display property that most of the validation controls
share uses a bit of DHTML to determine the details about how exactly a
validation message is shown and hidden at run time. If you set this property to
the Static enumeration, space will be reserved on the page to display the error
message. Conversely, when the property is set to Dynamic, page content will be
moved around as needed to make room for the validation error message when it
needs to be displayed. It can be slightly jarring for some users to have page
content moving around on them as they are typing, so I suggest using a Static
Display in most cases.
The ASP.NET validation controls are powerful, flexible,
and easy to use. With little or no code you can bulletproof your data entry
forms to ensure data integrity throughout. Small efforts like these can make
the difference between a database application that lives for decades, and one
that gradually decays beyond repair.
The sample code in
this article is available for download.
Steve C. Orr is an
MCSD and a Microsoft MVP in ASP.NET. He s been developing software solutions
for leading companies in the Seattle
area for more than a decade. When he s not busy designing software systems or
writing about them, he can often be found loitering at local user groups and
habitually lurking in the ASP.NET newsgroup. Find out more about him at http://Steve.Orr.net
or e-mail him at mailto:Steve@Orr.net.