Building a Better Custom Validator
posted on 2005-01-05 at 00:12:09 by Joel Ross
I recently had a need to have a custom validator that would validate even when the textbox was empty. My first solution was to use a custom validator in conjunction with a required field validator. That worked just fine.
Until I found a situation where the field would sometimes be required and sometimes not be required. And it wasn't based on entries in another field. It had to do with whether a whole form was filled out - if nothing was populated, then the form is fine. If any one piece was populated, then it should validate everything.
So the custom / required validator combo didn't work for me. So I decided to build my own validator. It's very similar to the custom validator (I used that as my code sample using Reflector).
Here's the code for the validator:
1: using System;
2: using System.ComponentModel;
3: using System.Security.Permissions;
4: using System.Web;
5: using System.Web.UI;
6: using System.Web.UI.WebControls;
7:
8: namespace RossCode.Web.UI.WebControls
9: {
10: /// <summary>
11: /// Summary description for RequiredCustomValidator.
12: /// </summary>
13: [ToolboxData("<{0}:RequiredCustomValidator runat=server ErrorMessage=\"RequiredCustomValidator\"></{0}:RequiredCustomValidator>"), DefaultEvent("ServerValidate")]
14: public class RequiredCustomValidator : System.Web.UI.WebControls.BaseValidator
15: {
16: static RequiredCustomValidator() {
17: EventServerValidate = new object();
18: }
19:
20: public RequiredCustomValidator() { }
21:
22: protected override bool EvaluateIsValid() {
23: string textValue = "";
24: string controlId = base.ControlToValidate;
25:
26: if (controlId.Length > 0) {
27: textValue = base.GetControlValidationValue(controlId);
28: }
29:
30: return OnServerValidate(textValue);
31: }
32:
33: public virtual bool OnServerValidate(string value){
34: ServerValidateEventHandler handler1 = (ServerValidateEventHandler) base.Events[RequiredCustomValidator.EventServerValidate];
35: ServerValidateEventArgs args1 = new ServerValidateEventArgs(value, true);
36: if (handler1 != null) {
37: handler1(this, args1);
38: return args1.IsValid;
39: }
40: return true;
41:
42: }
43:
44: private static readonly object EventServerValidate;
45:
46: public event ServerValidateEventHandler ServerValidate {
47: add {
48: base.Events.AddHandler(RequiredCustomValidator.EventServerValidate, value);
49: }
50: remove {
51: base.Events.RemoveHandler(RequiredCustomValidator.EventServerValidate, value);
52: }
53: }
54:
55: protected override bool ControlPropertiesValid() {
56: string controlId = base.ControlToValidate;
57: if (controlId.Length > 0) {
58: base.CheckControlValidationProperty(controlId, "ControlToValidate");
59: }
60: return true;
61: }
62:
63: public string ClientValidationFunction {
64: get {
65: object obj1 = this.ViewState["ClientValidationFunction"];
66: if (obj1 != null) {
67: return (string) obj1;
68: }
69: return string.Empty;
70: }
71: set {
72: this.ViewState["ClientValidationFunction"] = value;
73: }
74: }
75:
76: protected override void AddAttributesToRender(HtmlTextWriter writer) {
77: base.AddAttributesToRender(writer);
78: if (base.RenderUplevel) {
79: writer.AddAttribute("evaluationfunction", "RequiredCustomValidatorEvaluateIsValid");
80: if (this.ClientValidationFunction.Length > 0) {
81: writer.AddAttribute("clientvalidationfunction", this.ClientValidationFunction);
82: }
83: }
84: }
85: }
86: }
I'm not sure why, but for some reason, it doesn't work in design view. But if you know me or read this blog regularly, you'll know I don't much care for design view anyway. Even without it, this works.
The ServerValidate event fires even when nothing is in the box. I am now thinking about doing my own custom control for the regular expression validator too - when I give it a regex, and the regex doesn't allow blanks, why is that valid?
Anyway, here's the code. Feel free to use it as you please.
Categories: ASP.NET