Click here to Skip to main content
Email Password   helpLost your password?

Sample Image - Validator.gif

Introduction

I've been playing with ASP.NET since Beta 1, and I have to admit that I love it! What used to take days in traditional ASP can now be done in an afternoon. One of the few complaints that I have is ASP.NET's implementation of validators. While I certainly believe that validation controls extremely are time saving, I'm not really thrilled with the ones provided by Microsoft. They work great if you only have a few items to validate, but can become a chore to maintain, when there are many fields that need validation.

What I wanted was a single control that you could drop on to your form, that would handle all the validation for you. This way, you have one validator to maintain, not 10, or whatever. So I wrote this custom Validator control. Included in the download is the Validator control itself, its source code (don't run away screaming now, it's in VB.NET...), and 3 JavaScript files. I couldn't find an elegant way to use Microsoft's JavaScript files, and they didn't seem to support the DOM specs, so I wrote my own files. These need to be placed in your \inetpub\wwwroot\_vti_script directory. Validation.js is the main JavaScript file, which sets up some prototype functions, then links to one of the other two files depending on your browsers capability. ValidationDOM.js is, of course, for DOM compliant browsers (NS6.2+, IE5+). ValidationIE.js is for earlier versions of IE. I chose not to support early versions of Netscape, because there doesn't seem to be an elegant version of document.getElementById or document.all, and so Validation.js simply forces early versions of Netscape to use server side validation only.

Using the control

That being said, an explanation of its use is in order. The Validator control is derived from System.Web.UI.Webcontrols, and so has the standard properties of a web control. It also has 4 additional properties:

Once the Validator has been added to a page, you need to tell it what to validate. By either right-mouse clicking on the control, or looking at the designer verbs area just below the property window, you'll notice a menu/verb item marked 'Edit Fields'. A dialog then appears (as shown in the screenshot) allowing you to modify the control's collection of validations. Clicking on one of the buttons, adds a validator to the list, while clicking Remove will, of course, remove the selected item. All validation options share some common properties:

Next is a summary of the additional properties of each of the validation types:

In order to use server side validation for the CustomFieldValidator, you need to handle the CustomFieldValidation event of the Validator object. All CustomFieldValidator items that you've added to the control will route through this same event, so you need a way to distinguish between them. This is where the Name property of the CustomFieldValidator comes in hand. It is sent in the CustomFieldValidatorEventArgs class to the event handler.

Public Sub Validator1_CustomFieldValidation(ByVal sender As Object, _
         ByVal E As CP.Validator.CustomFieldValidatorEventArgs) _
         Handles Validator.CustomFieldValidation
    Select Case E.Name
        Case "IsEven"
            If CInt(DirectCast(E.ControlToValidate, _
                         TextBox).Text) Mod 2 = 0 Then
                E.IsValid = True
            Else
                E.IsValid = False
            End If
    End Select
End Sub

To add a validation to the control at run time, use the Validators collection of the control:

Validator1.Validators.Add(New ReqFieldValidator("txtName", 
                                       "Enter a name", ""))

I've tested it every way that I could think of, and it seems to be stable. However, since this is the control's first release to the public, you should expect bugs. If you run across any, please either post them here, or E-mail me directly at jamie.nordmeyer@mcgnw.com, and I'll do my best to fix it. Also, if you have any comments, concerns, or suggestions, let me know.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralMy vote of 1
ashney
1:45 31 Dec '09  
wrong article title
GeneralPray tell, what does this article have to do with Windows Forms?
cjard
3:11 14 Jun '09  
This is web forms, not Windows Forms. Thanks for wasting my time. Please rename your article.
GeneralRe: Pray tell, what does this article have to do with Windows Forms?
tonymontana82
11:29 15 Jul '09  
cjard wrote:
This is web forms, not Windows Forms. Thanks for wasting my time. Please rename your article.

Well said, this is WEB forms, not win forms! thanks for wasting my time also
GeneralQuestion and suggestion
Evert Wiesenekker
3:46 17 Apr '07  
One question:

Should the code of method 'Validate' of the if else not be swapped (because FocusChange mode checks validates now every control)?

Two suggestions:

1. Code to clear each errormessage, eg:

Class 'Validator':

public void Clear()
{
foreach (Control control in this.infos.Keys)
{
ValidationInfo info = this.infos[control];
info.Clear();
}
}

Class 'ValidationInfo':

public void Clear()
{
this.errorProvider.SetError(control, String.Empty);
}

2. A method to specifically Validate a control. Now all controls will be validated upon calling Validate.

public bool Validate(Control controlToValidate)


Nice article!


GeneralThe Perfect Solution
kooks2k
21:18 31 Jan '07  
Thanks very much for this awsome contol,it provides all what i need.
GeneralDataGridView
DanielRabe
6:48 28 Nov '06  
Hi

Has anyone managed to get this to work the the DataGridView? That's my current challenge...

Daniel
Generalerror provider
shabonaa
10:18 20 Oct '06  
does this validator differ from error provider? if yes what is the difference?
GeneralThanks a lot!
Piotr Nogalski
3:18 7 Oct '06  
Your validator works excellent! It helped me a lot. Thanks again Smile
GeneralRemoving icon, when disabling Control
drJoene
8:37 2 Oct '06  
Hi,

This is exactly what i need! Thank you!

Still one question:

How do i remove the icon when i'm removing the validation on a Control;

Little example:

if (enableGroupbox1)
{
// Enable grpBox1
this.grpBox1.Enable = true;

// Add validation to fields
validator1.SetType(txtFirstName, Itboy.Components.ValidationType.Required);
validator1.SetRequiredMessage(txtFirstName, "Firstname is required");
}
else
{
// Disable grpBox1
this.grpBox1.Enable = false;

// Remove validation
validator1.SeType(txtFirstName, Itboy.Components.ValidationType.None);
validator1.SetRequiredMessage(txtFirstName, null);
}

Now, when i disable the groupbox, and didn't fill in the Control txtFirstName correctly (when it was enabled), there is still the little icon.

Any idea's howto remove this?

Thanks in advance,

Grt Jeroen



GeneralNice, but...
twesterd
12:14 7 Jun '06  
Okay, this seems to be the #1 area I see application design errors (in my opinion). Long ago, especially with Web Apps, the validation had to be separate from the data object itself due the the nature of how web browsers communicated with data servers.

This is no longer the case, but the old design patterns refuse to leave. The UI, whether it is a web browser or a web form, should not know anything about validation... zip, zero, nada. Think about it, when a designer creates a data object (class), that class should set the validation rules about itself, not the textbox, or grid or whatever control is used to display the data.

You began the article with having to duplicate code, hence your validation control. But, you still must duplicate code for every form (browser or winform) that provides access to the data and your actual data object has a big gaping whole that allows bad data if you design a new form and miss "something" in the validation.

I suggest you read up on the IEditableObject, IPropertyChangeNotification, and IDataErrorInfo interfaces. Object classes should validate themselves and simply provide the information to the UI via these interfaces.

I do not have one line of validation code in the UI: zip, zero, nada on any form, yet the validation is robust. Furthermore, I create the validation for let's say 'Email Address', 'Credit Card Number', etc in ONE place in the business tier and the object itself simply calls IsValid(Email,textFromProperty, out message), if it fails the validation, then IDataErrorInfo is trigered for that property and the form displays the error without any validation code in the UI. Furthermore, since "rules" are consolidated in one location and the rule for, let's say 'Credit Card Number', changes, then I change it in ONE spot and I know every place that spawned from it(depends on it) updates without making any other "unecessary" changes to code.

My advice: never, ever place validation within the presentation tier - never... for the very same reasons you began the article with. Just because the old limitations have spawned bad habits that are still very popular does not mean they should be continued.

This is a perfect example of the "popular way" does not mean its the "right" way to go.

Having said all that, it was a nice article for what it was trying to do, but I personally would never validate data in this manner and I still rated your article high, it was done well.

Trevor
GeneralRe: Nice, but... I'm looking forward to your article...
Peter Hancock
6:27 23 Aug '06  
Hmmm.... a good theoretical response Trevor. I'm looking forward to seeing your article illustrating it practically Poke tongue

Peter Hancock
My blog is here
And they still ran faster and faster and faster, till they all just melted away, and there was nothing left but a great big pool of melted butter
"I ask candidates to create an object model of a chicken." -Bruce Eckel

GeneralRe: Nice, but... I'm looking forward to your article...
Brisbane
20:56 13 Jun '07  
Smile A good example of how to keep validation in the business layer can be found in the Microsoft patterns and practices validation block, it is expert level stuff and takes a while to be able to use and understand but it is the way to go if you are looking to build enterprise level applications
GeneralRe: Nice, but...
Zoodor
6:34 14 Sep '06  
Thanks for the info. about those interfaces Trevor, I am going to be looking into using these for the project I'm working on Smile

One note is that the 'IPropertyChangeNotification' interface is actually 'INotifyPropertyChanged'. And for anyone else looking for them, they're in the System.ComponentModel namespace.
GeneralRe: Nice, but...
Paul Menefee
7:13 26 Sep '06  
Excellent point. Provide a clean, practical POC article and you've have a winner.

"We have a proven antidote to war: free trade." ~ Paul Zane Pilzer

GeneralRe: Nice, but...
Pink Floyd
8:19 2 Nov '06  
Not that I'm a smartass but check this out:

http://www.codeproject.com/csharp/DelegateBusinessObjects.asp?df=100&forumid=308172&fr=26[^]
GeneralValidating UserControl
Ali Youssef
6:55 27 Apr '06  
Excellent work,

I noticed this control work only on a Form. Is there a way to extened it to be dropped in a UserControl, Basically my user control has all the window elements so I will need to drop the Validatior in the user control

Thank You

Ali
GeneralRe: Validating UserControl
dwegmann
13:20 19 May '06  
I would suggest it to. UserControl support is missing at this time to get it fully useful.

Thanks.
GeneralRe: Validating UserControl
DanielRabe
6:58 10 Oct '06  
Great code! You can alter this project to work with User Controls by doing the following:

//comment out or delete code in /* */ and add the following to the Validator.cs as shown in the sample.
public override void InitializeNewComponent(System.Collections.IDictionary defaultValues)
{
components = new System.ComponentModel.Container();
/* // Set container form as validator's form.
((Validator)this.Component).Form = (Form)this.ParentComponent;

base.InitializeNewComponent(defaultValues);*/
}

//dont forget to declare "components":
private System.ComponentModel.Container components = null;

Thanks to the Noogen project for help in this (search this site for Noogen)
QuestionIcon
zizkam
4:10 27 Apr '06  
I see that you have the same problem with the error icons as I have. I haven't found anywhere on the internet answer how to make the error icons round. Do you see the ugly artifacts that are around the icon? It should be round. When you make the icon blink and after some time they stop blinking, they looks nice and round. But try to catch the window and move it off-screen so the icons are not visible and then move it back - and see? The icons get ugly borders... The same problem is when you disable blinking. It seems like problem with rendering alpha channel. Have you anyone found a workaround to this behaviour?

AnswerRe: Icon
Rick Engelking
6:18 27 Apr '06  
I think they were designed to look like a STOP sign - 8 sided.

Probably not a good idea from a global perspective...
JokeVery cool
davepermen
22:18 26 Apr '06  
this is a very cool tool. I was about to write something similar, but you where faster. It works great so far.

I noticed 1 thing: if i write something wrong into each, the blinking of all of them can be annoying (as they all blink at different times), but hey.. i just disabled blinking (fits more my style anyways).

I changed one other thing:
string oldmessage = this.errorProvider.GetError(control);
if (string.IsNullOrEmpty(oldmessage) != string.IsNullOrEmpty(message))
{
int shift = string.IsNullOrEmpty(oldmessage) ? -this.errorProvider.Icon.Width : +this.errorProvider.Icon.Width;
control.Width += shift;
}
this.errorProvider.SetError(control, message);

that way, the actual sign fits into the rectangle of the invalid control.


thanks, this code will definitely be put to use


Last Updated 26 Apr 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010