ASP.NET CustomValidator ... ARRRGH!
- Posted in:
- ASP.NET WebForm
- Rant
I've never been a fan of ASP.NET Validation controls (perhaps old habit dies hard). Well, the real reason is because I've tried using them before and it felt very quirky and buggy, especially when you just started using it. For example, one moment it works and then suddenly it does not work anymore and you are left standing in confusion wondering what the heck is actually going on in the backend. In the end, I found that writing my own client side validation routine will give me complete control over how and what to validate (as it was in classic ASP). That's right... I'm a control freak and am proud of it *hahaha*.
But in the last two web projects, I finally decided to give them a second try. Sure, why not, right? Less form validation code to write... right? Less headache, right? At least that was the premise of the Validation controls.
So, I started with the easiest one, RequiredFieldValidator ... compiled it, ran it, tested it. Great, it worked. Piece of cake... Perhaps I should change my thinking about these neat validators stuffs, hmm... or so I thought.
Great, next, let's try the CustomValidator to validate a dropdown list like the one described below. The end result that I was going for is that if the value of the control to be validated is empty, show validation error. (Perhaps I should clear it a bit more... if the first dropdown list item is currently selected, which just happen to have empty value - it's a dummy option -, return fail).
The controls are setup as:
<asp:customvalidator id="DisciplineCustomValidator" runat="server" ClientValidationFunction="ValidateDiscipline" ControlToValidate="DisciplineDropDownList" ErrorMessage="Invalid discipline choice." Display="Dynamic">*</asp:customvalidator> <asp:dropdownlist id="DisciplineDropDownList" runat="server"></asp:dropdownlist>
The dropdown list, after data bound, will have the following OPTION elements...
<option value=“A“>A - Discipline A</option> <option value=“B“>B - Discipline B</option> <option value=“C“>C - Discipline C</option>
and the Javascript client side validation code as follow:
function ValidateDiscipline(source, args) { args.IsValid = false; // force failure to test... }
and the server side validation code as follow:
private void DisciplineCustomValidator_ServerValidate( object source, System.Web.UI.WebControls.ServerValidateEventArgs args) { args.IsValid = false; // force failure to test ... }
Compiled it, ran it, tested it... Great it work as expected.
Having my faith in the ASP.NET Validation control renewed, I decided to have a little bit more fun with it.
Next step, I added a dummy option for my DisciplineDropDownList... after databinding, the list should contain the following OPTIONs...
<option value=““>- - Select a Discipline - -</option> <option value=“A“>A - Discipline A</option> <option value=“B“>B - Discipline B</option> <option value=“C“>C - Discipline C</option>
Of course, user should not choose the first option in the list... that would be bad... No no no. *wiggle index finger from side to side* Bad user... very very bad user. You no no choose the Select a Discipline option. No you don't. Great, now it's decided, the ValidateDiscipline JavaScript function should take care of this...
so, I changed my Javascript routine to something like so...
function ValidateDiscipline(source, args) { args.IsValid = (args.Value != ““); }
and the server side validation code as follow:
private void DisciplineCustomValidator_ServerValidate( object source, System.Web.UI.WebControls.ServerValidateEventArgs args) { args.IsValid = (args.Value != string.Empty); }
Compiled it, ran it, tested it. Well, guess what... the validation stopped working. Hmm... *boggled* *getting irritated* *started cursing like a mad monkey* *pulled hair frustratedly* - I swear... sometimes I think I pulled my hair too much that I've become more and more balder...sigh.
Both client side and server side validation just do not want to trigger for whatever reason.
Long story short, after googling for about 30 minutes trying to get to the root of the problem, and not finding real solution to this problem, I've decided to put the code back in the state where it last worked.
So the options are back to...
<option value=“A“>A - Discipline A</option> <option value=“B“>B - Discipline B</option> <option value=“C“>C - Discipline C</option>
Compiled it, ran it, tested it. !^&*#!(* it worked again.
It looks like the CustomValidator does not like the argument value to be empty string. Lesson learned.
Jimmy's ASP.NET CustomValidator rule #1: Thou shalt not custom validate against empty string (well not exactly).
The long version: If you specify a ControlToValidate attribute in the CustomValidator and the default value to validate againsts is an empty string value, the control will fail miserably regardless what you are putting into the client side validation function. It will always return as valid.
Is this a bug? or by design? You tell me...
If you should find yourself needing to do this, you can do the following...
Do not specify the ControlToValidate attribute in the CustomValidator tag. And re-code your validation routine to like so...
function ValidateDiscipline(src, args) { var e = document.getElementById(“DisciplineDropDownList“); args.IsValid = (e.options[e.selectedIndex].value != ““) }
or in my case, like this...
function ValidateDiscipline(src, args) { var e = document.getElementById(“DisciplineDropDownList“); args.IsValid = (e.selectedIndex > 0); }
Till next validation control quirkiness... Nuff said.