8.6 Custom ValidationThere are times when the validation of your data is so specific to your application that you will need to write your own validation method. The CustomValidator is designed to provide all the infrastructure support you need. You simply point to your validation method and have it return a Boolean value: true or false. The CustomValidator control takes care of all the rest of the work. Because validation can be done on the client or on the server, depending on the browser, the CustomValidator has attributes for specifying both a server-side and a client-side method for validation. The server-side method can be written in any .NET language, such as C# or VB.NET, while the client-side method must be written in a scripting language understood by the browser, such as VBScript or JavaScript. You'll create a simple form that will request an even number from the user, and report the error if the number is not evenly divisible by 2. You can imagine, however, that you could perform a checksum on a credit card or ISBN or otherwise perform complex data checking. The heart of this example is the CustomValidator control: <asp:CustomValidator id="cvEven" controlToValidate="txtEven" Display="Static" runat="server" ClientValidationFunction="ClientValidator" OnServerValidate="ServerValidator"> Well, that's odd... </asp:CustomValidator> The CustomValidator takes many of the usual attributes, such as an ID, runat, ControlToValidate, and Display. In addition, this validator has an attribute that identifies the script method to run for client-side validation (ClientValidationFunction) and one that defines the method to run for server-side validation (OnServerValidate). You'll provide JavaScript for the client-side validation: <script language="javascript"> function ClientValidator(source, args) { if (args.Value % 2 == 0) args.IsValid=true; else args.IsValid=false; return; } </script> This simple function examines the value passed to the script by the validator, and if it is an even number, it returns true; otherwise, it returns false. You also need a server-side method: Protected Sub ServerValidator(ByVal source As Object, _ ByVal e As ServerValidateEventArgs) Dim evenNumber As Int32 = Int32.Parse(e.Value) If evenNumber Mod 2 = 0 Then e.IsValid = True Else e.IsValid = False End If End Function In C#, it looks like this: protected void ServerValidator (object source, ServerValidateEventArgs e) { try { int evenNumber = Int32.Parse(e.Value); if (evenNumber % 2 == 0) e.IsValid = true; } catch (Exception) { // error handler here } } This method does the same thing as the client-side validator, only in VB.NET or C# rather than in JavaScript. There are a few things to notice about these methods. First, the value that the CustomValidator is examining is passed to your routine as the Value property of the ServerValidateEventHandler event argument. You can convert that string to an int in C# or an Integer in VB.NET using the Base Class Library Int32 object's static Parse method, as shown. The C# example wraps the conversion in a try/catch block to handle any exception that might be thrown. The complete .aspx file is provided in Example 8-7, with the code-behind file in Example 8-8 for C#, and Example 8-9 for VB .NET syntax. Example 8-7. Custom validator page<%@ Page Language="C#" AutoEventWireup="false" Codebehind="WebForm1.aspx.cs" Inherits="CustomValidator.WebForm1" EnableSessionState="True"%> <HTML> <HEAD> <meta name=vs_targetSchema content="Internet Explorer 5.0"> <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0"> <meta name="CODE_LANGUAGE" Content="C#"> </HEAD> <body MS_POSITIONING="GridLayout"> <form method="post" runat="server" ID="Form1"> <table> <tr> <td colspan="2"> <h5>Please enter an even number</h5> </td> </tr> <tr> <td> <asp:TextBox Width="50" ID="txtEven" Runat="server" NAME="txtEven"/> </td> <td> <asp:CustomValidator id="cvEven" controlToValidate="txtEven" Display="Static" runat="server" ClientValidationFunction="ClientValidator" OnServerValidate="ServerValidator"> Well, that's odd... </asp:CustomValidator> </td> </tr> <tr> <td> <asp:Button ID="btnValidate" Text="Validate" Runat="server"></asp:Button> </td> <td> <asp:Label ID="lblMsg" Text="" Runat="server"></asp:Label> </td> </tr> </table> <script language="javascript"> function ClientValidator(source, args) { if (args.Value % 2 == 0) args.IsValid=true; else args.IsValid=false; return; } </script> </form> </body> </HTML> Example 8-8. C# code-behind filenamespace CustomValidator { using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; public class WebForm1 : System.Web.UI.Page { protected System.Web.UI.WebControls.TextBox txtEven; protected System.Web.UI.WebControls.Button btnValidate; protected System.Web.UI.WebControls.Label lblMsg; public WebForm1( ) { Page.Init += new System.EventHandler(Page_Init); } protected void Page_Init(object sender, EventArgs e) { InitializeComponent( ); } #region Web Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent( ) { this.btnValidate.Click += new System.EventHandler(this.btnValidate_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion public void ServerValidator (object source, ServerValidateEventArgs e) { try { int evenNumber = Int32.Parse(e.Value); if (evenNumber % 2 == 0) e.IsValid = true; } catch (Exception) { // error handler here } } protected void btnValidate_Click(object sender, System.EventArgs e) { if (Page.IsValid) lblMsg.Text = "Valid."; else lblMsg.Text = "Not Valid."; } } } Example 8-9. VB.NET code-behind filePublic Class WebForm1 Inherits System.Web.UI.Page #Region " Web Form Designer Generated Code " 'This call is required by the Web Form Designer. Private Sub InitializeComponent( ) End Sub Protected WithEvents txtEven As System.Web.UI.WebControls.TextBox Protected WithEvents cvEven As System.Web.UI.WebControls.CustomValidator Protected WithEvents btnValidate As System.Web.UI.WebControls.Button Protected WithEvents lblMsg As System.Web.UI.WebControls.Label Private designerPlaceholderDeclaration As System.Object Private Sub Page_Init(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Init 'CODEGEN: This method call is required by the Web Form Designer 'Do not modify it using the code editor. InitializeComponent( ) End Sub #End Region Protected Sub ServerValidator(ByVal source As Object, _ ByVal e As ServerValidateEventArgs) Try Dim evenNumber As Integer = Int32.Parse(e.Value) If (evenNumber Mod 2 = 0) Then e.IsValid = True End If Catch ' error handler here End Try End Sub Private Sub btnValidate_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnValidate.Click If (Page.IsValid) Then lblMsg.Text = "Valid." Else lblMsg.Text = "Not Valid." End If End Sub End Class |