Technologies Used:
ASP.NET
C#
Validation Web server controls
Level of Difficulty
Intermediate
Hello fellow code warriors!
If you recall, in newsletters-aspnetcsharp.htm, we learned how to enforce better quality control in your Web
software projects by the use of validation. To do this, we used a variety of ASP.NET’s Validation Web server controls to set criteria and test the accuracy
of the data, and return error messages to the Web browser if data entered within
the WebForm’s elements did not match these criteria.
You’ll also recall that I used a combination of validation controls to ensure
the form was valid, meaning the user filled out their first name, last name and
e-mail address, and then tested to make sure the user’s e-mail address was in
the proper format. I also wrote a custom subroutine that checked if none of the
checkboxes in the form were checked, and if so, returned an error message to the
user letting her know that at least one newsletter had to be signed up for.
The only thing that’s less than optimal about this second validation technique
is that the browser is forces to make a call back to the server to do the
validation, and performance-wise, this roundtrip adds unnecessary overhead to
your app. Also, from a user-friendliness standpoint, this forces the user to
have to click on the “Back” button to select at least one choice, which is a
minor inconvenience, but an inconvenience nonetheless.
One developer wrote me and asked if there was an alternate way to do this, using
similar validation controls:
Hi Jason,
I’m curious as to whether a developer would be able to use a custom validation routine and go all the way back to the server? Couldn’t it just be done at the client and be faster? I know there’s server-side validation that can be done in ASP.NET, but would simple JavaScript be any better? Thanks!
Johann
Stuttgart, Germany
The answer? Absolutely! I actually did this intentionally to show you the
various ways that you can accomplish the same thing in ASP.NET (OK, I’m lying…I
was lazy). Perhaps the best thing about the .NET Framework is that while it
provides comprehensive functionality through it’s really, really big library of
pre-shipped classes, it’s completely extensible. If you think you can do
something more efficiently, with less code, or more suitable to your
application, or you just don’t like the way Microsoft’s defined how to get
something done, and you always roll you own solution.
In this installment of “Dev Dungeon” we’re going to look at the ASP.NET
CustomValidator server control, and implement it to enforce our business rule,
requiring that at least one newsletter must be subscribed to.
I’ve developed a simple WebForm that emulates part of the form we looked at in
Part 1. Looking at our page-level code in the form itself, you can see that I’ve
laid out four server controls, namely a Label, CheckBoxList, a Button, and
something new – our CustomValidator control. Contrary to the other validation
controls that ASP.NET provides, the CustomValidator allows you to define
programming logic in your WebForm’s <SCRIPT> blocks (like we’re doing here), or
in a code-behind file, like we saw in Part 2.
When using a CustomValidator on a page, a developer uses the CustomValidator
class and writes methods to ensure the validity of a form, and then sets the
OnServerValidate and ClientValidationFunction properties. This not unsurprisingly allows you to test for validation at the server and client
levels, respectively. In the case of the former, any arguments are passed to the
function through the ServerValidateEventArgs parameter of the method’s
signature. In the case of the latter, client-side JavaScript is typically used
to validate the form’s contents upon submission. Most of the other properties
inherent to validation controls, such as ErrorMessage, Display, and Text. See
the .NET Framework documentation or
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWebUIWebControlsCustomValidatorClassTopic.asp
for more on the CustomValidator class.
|
User_Choice method
So, getting back to our WebForm, we’ve defined two methods – the private method
User_Choice starting on line 24 and the public ValidateForm starting on line 39.
The first is wired to our CustomValidator control through the aforementioned
OnServerValidate event on line 61, and the latter is wired to our Button’s
OnClick event on line 62. Essentially, User_Choice iterates through the
CheckBoxList control, and tests to see if any of the boxes have been checked. As
you learned in Part 1, we’ve dynamically populated our CheckBoxList control at
design-time, so there’s no real way at run-time to know just how many elements
there are.
However, we know that each checkbox rendered to the page as an HTML <input
type=”text”> element can be accessed programmatically in our code as part of an
array, through the CheckBoxList’s Items collection. We use a simple for… loop in
lines 28-36 that checks if the item is checked (through the Selected property),
and if so, increment an integer variable we introduce, counter. This gives us a
running count of how many choices the user has selected.
Now, we use C#’s ternary operator on line 35 to evaluate the numeric value of
counter, and if it happens to be greater than 0, this means that the user
checked at least one of the boxes. In such case, we assign a value of false to
the boolean IsValid property, and if not, assign it as true.
ValidateForm method
In our second method, we simply test the value of the IsValid property in line
41. Because this is wired to the Button’s OnClick event, this cannot be
prematurely executed before User_Choice, ensuring the quality control we’re
after. If the value is true, we return a rather simple congratulatory message to
our Label’s Text property, and if not, we do the opposite. Notice how I’ve
declaratively used some of the various properties of the CustomValidator control
to generate an error message presented to the user.
Figure 1 shows the WebForm when browsing to it, before submission. Figure 2
shows the WebForm properly validated, and Figure 3 shows an invalid form
submission.
|
|
|
|
|
|
So why just not use client-side JavaScript???
The question of whether or not to use a simple JavaScript is a good one, and
very logical. Why spend the time writing two server-side methods when I could
just embed a JavaScript scriptblock to ensure
Using the CustomValidator server control in the way we’ve just done integrates
better with the life-cycle of your page. I openly recommend playing with various
implementations of custom server-side validation routines, and the .NET
Framework makes it very easy to roll your own. However, if you’re of the
programming flow
That we’ve populated our CheckBoxList control dynamically might make this tough
for a client-side JavaScript routine, because we’d have to know ahead of time
the specific values of the ID and Name attributes of the HTML Checkbox elements
to access them, if we were to use the DHTML document object model (DOM), which
would normally be the case. This is significantly easier using server-side
logic. The .NET Framework automatically assigns each element in a WebForm a
unique ID and/or Name, eliminating the chance for problems that would arise from
clashes. However, this still doesn’t make it any easier to program against them,
not knowing what they’ll be at design-time.
It’s not impossible – it would just take more work.
The best thing about the CustomValidator is that it gives you the option to use
server- events and/or client-side logic to ensure a WebForm is valid. You get
the integration with the naming system used by the .NET Framework and
customizability within the life-cycle of the page with server-side logic, plus
the quick response of a client-side JavaScript subroutine or function.
Best case scenario? I’d use both, in a professional setting.
So now that we’ve seen how to implement a custom validation rule, here’s your
homework. Re-develop Part 1 of our tutorial and implement the CustomValidator
server control instead of the generic routine we used originally. I think you’ll
be pleased with the reduction in code – and with the results.
Happy programming!
</jason>