Developing a Validator Control

This section discusses validation in the ASP.NET page framework and shows how you can develop your own library of validator controls.

Validation generally involves checking form data entered by a user. However, it could also involve other kinds of error checking. To provide an abstraction that encompasses different scenarios involving validation, the .NET Framework defines the System.Web.UI.IValidator interface, which has the following members.

public interface IValidator
{
   void Validate();
   string ErrorMessage {get; set;}
   bool IsValid {get; set;}
}
[Visual Basic]
Public Interface IValidator
   Sub Validate()
   Property ErrorMessage As String
   Property IsValid As Boolean
End Interface

The Validate method performs error-checking logic and sets the IsValid property. The ErrorMessage property contains an error string supplied by a page developer.

The Page class exposes the Validators property, which is a list of all the IValidator types on the page. Any class that implements the IValidator interface is considered to be a validator and can be added to the Validators property of its containing page. A page keeps track of the error status of its validators and updates its own overall error status accordingly.

The most common validator types are validator controls that render UI on the client to flag input errors. For information about validator controls that ship with the .NET Framework SDK, see the ASP.NET QuickStart —> ASP.NET Web Forms —> Server Control Form Validation. The following list summarizes the characteristics of validator controls in the .NET Framework and should be useful to anyone building a validator controls library:

  • Validator controls are separate from the controls they validate. (To participate in validation, a server control must expose a property to validate by marking it with the ValidationPropertyAttribute.)
  • Multiple validator controls can be associated with one input control.
  • The appearance and the error message of a validator control are customizable by the page developer.
  • Validator controls are script-enabled and perform the same error checking on (uplevel) clients as on the server.
  • On uplevel clients, validator controls display input errors without a server round trip. Per-field validation errors are displayed on the client as soon as the user tabs to a different field, and required field validation errors and an error summary are displayed when the user submits the form.
  • Page developers can provide client-side script that supplements or replaces the client-side error checking performed by a validator control.

Common validation functionality is implemented by the abstract base class System.Web.UI.WebControls.BaseValidator, which implements IValidator, registers client-side script with the page, and provides base rendering logic. The concrete validator classes such as RequiredFieldValidator, RegularExpressionValidator, and CustomValidator derive from BaseValidator and add their own specific functionality. A summary of validation error messages is provided by the ValidationSummary control. ValidationSummary itself is not a validator (it does not implement IValidator) and derives from WebControl. ValidationSummary accesses the Validators collection of a page to get the error message of each validator registered with the page.

If you have installed the .NET Framework SDK or Visual Studio .NET, you can see the script library that is emitted by BaseValidator by looking at the file in the virtual rooted directory aspnet_client/system_web/<version of SDK installed>. For information about emitting client-side script, see Client-Side Functionality in a Server Control.

The following discussion describes the key steps in developing a validator control that provides base validation functionality. Follow these steps if you want to develop a base validator control for a custom validator library or a custom validator control that provides all the necessary validation functionality. You do not have to implement these steps if you are interested in a simpler scenario such as extending an existing validator. For those cases, see the examples that extend a base validator in Validator Control Samples.

To implement a validator

Note   Steps 1-4 in the following list are common to all validators, including server-side validator classes that are not controls. Steps 5-10 are for controls that provide UI and emit client-side script.

  1. Define a class that implements IValidator. If the validator is a control it must additionally derive directly or indirectly from Control. Validator controls in the .NET Framework derive from System.Web.UI.WebControls.Label, as shown in the following example.

    public abstract class BaseDomValidator : Label, IValidator {...}
    [Visual Basic]
    MustInherit Public Class BaseDomValidator
       Inherits Label
       Implements IValidator
       ... 
    End Class
    

    Note   Unless intended as a base class, your validator does not have to be abstract.

  2. Implement the contract of IValidator. The following example shows how you can implement IValidator. Also see the Base Validator Control Sample.

    public string ErrorMessage {
                get {
                    object o = ViewState["ErrorMessage"];
                    return((o == null) ? String.Empty : (string)o);
                }
                set {
                    ViewState["ErrorMessage"] = value;
                }
            }
    public bool IsValid {
                get {
                    return isValid;
                }
                set {
                    isValid = value;
                }
            }
    public void Validate() {
    ...
    // A base validator cannot supply all the validating logic.
    // You can implement common functionality here and invoke an 
    // abstract method that is overridden by derived classes to
    // provide validation logic.
                IsValid = EvaluateIsValid();
            }
    
    // This method is overridden by a concrete class that extends 
    // the base validator to supply specific validation logic.
    protected abstract bool EvaluateIsValid();    
    [Visual Basic]
    Public Property ErrorMessage() As String Implements IValidator.ErrorMessage
       Get
          Dim o As Object = ViewState("ErrorMessage")
          If o Is Nothing Then
             Return String.Empty
          Else
             Return CStr(o)
          End If
       End Get
       Set
          ViewState("ErrorMessage") = value
       End Set
    End Property
    
    Public Property IsValid() As Boolean Implements IValidator.IsValid
       Get
          Return _isValid
       End Get
       Set
          _isValid = value
       End Set
    End Property
    
    Public Sub Validate() Implements IValidator.Validate
       ...
       ' A base validator cannot supply all the validating logic.
       ' You can implement common functionality here and invoke an 
       ' abstract method that is overridden by derived classes to
       ' provide validation logic.
       IsValid = EvaluateIsValid()
    End Sub
    
    ' This method is overridden by a concrete class that extends 
    ' the base validator to supply specific validation logic.
    Protected MustOverride Function EvaluateIsValid() As Boolean
    
  3. Add the validator to the Validators property of its containing page when the page is initialized, by overriding the OnInit method as follows.

    protected override void OnInit(EventArgs e) {
                base.OnInit(e);
                Page.Validators.Add(this);
            }    
    [Visual Basic]
    Protected Overrides Sub OnInit(e As EventArgs)
       MyBase.OnInit(e)
       Page.Validators.Add(Me)
    End Sub    
    

    Note   If your validator is not a control, this step must be performed by the page developer in the Page_Load method.

  4. Remove the validator from the Validators property of its containing page when the page unloads, by overriding the OnUnload method as follows.

    protected override void OnUnload(EventArgs e) {
                if (Page != null) {
                    Page.Validators.Remove(this);
                }
                base.OnUnload(e);
            }    
    [Visual Basic]
    Protected Overrides Sub OnUnload(e As EventArgs)
       If Not (Page Is Nothing) Then
          Page.Validators.Remove(Me)
       End If
       MyBase.OnUnload(e)
    End Sub    
    

    Note   If your validator is not a control, this step must be performed by the page developer in the Page_Unload method.

  5. Define a property that allows a user to associate an input control to validate with the validator. In ASP.NET validator controls, this property is named ControlToValidate; it is defined as shown in the Base Validator Control Sample.

  6. Define a property that allows a user to choose whether the control should emit client-side script. In ASP.NET validator controls, this property is named EnableClientScript; it is defined as shown in the Base Validator Control Sample.

  7. Prepare the client-side script library to be packaged with your validator control and place it in the correct directory on the server so that it can be used by other applications and does not create versioning conflicts. For details, see the discussion in Client-Side Functionality in a Server Control. For an example of a script library, see Script Library for Validator Sample.

  8. Invoke the methods of Page that emit client-side script. For details, see the discussion in Client-Side Functionality in a Server Control and see the implementation in the Base Validator Control Sample. These scripting methods are invoked from the PreRender and Render methods.

  9. Implement rendering logic by overriding the AddAttributestoRender and Render methods. For an example, see the implementation in the Base Validator Control Sample.

All the steps shown here are implemented in the Base Validator Control Sample.

See Also

Validator Control Samples | Client-Side Functionality in a Server Control