Recipe 3.9. Performing Validation Programmatically to Execute Your Own Application-Specific Logic


Problem

You have two logical sections on a form with controls that require different validation as a function of the button the user clicks. You want to have programmatic control over the validation performed because your application needs to carry out its own application-specific logic, such as when you want to check a new user's registration against a database.

Solution

For each group of controls and their associated form-submit button, set the ValidationGroup attribute to a unique group name. This will cause only the controls with a group name matching the group name of the button to be validated when the button is clicked.

In the .aspx file:

  1. Set the ValidationGroup attribute of a form-submit button to a unique group name.

  2. Set the ValidationGroup attribute of each of the controls to be validated when the button is clicked to the same group name as the form-submit button.

  3. Set the form-submit button's CausesValidation attribute to False to disable both the client-side and server-side validation performed by ASP.NET when the button is clicked.

  4. Repeat steps 13 for each form-submit button and its associated controls.

In the code-behind class for the page, use the .NET language of your choice to:

  1. Add an event handler for each form-submit button.

  2. Add code to the event handler to get the collection of validators associated with the button.

  3. Iterate through the collection performing the required validation.

Figure 3-14 shows a typical form with normal, error-free output. Figure 3-15 shows the error message that appears on the form when a validation error occurs in the login section of the form. Figure 3-16 shows the error message that appears on the form when a validation error occurs in the register section of the form. Examples 3-16, 3-17 through 3-18 show the .aspx and code-behind files for our application that implements the solution.

Discussion

Periodically, you must control the validation process that ASP.NET normally provides to perform the validation in a nonstandard way. ASP.NET provides the ability to get a collection containing a specific group of or all validators on a form. A collection of all validators on a form can be obtained as shown below:

 

Dim allValidators As ValidatorCollection … allValidators = Page.Validators

ValidatorCollection allValidators; allValidators = Page.Validators;

A collection of validators for a specific group on a form can be obtained as shown below:

 

validators = Page.GetValidators([name of desired group])

validators = Page.GetValidators([name of desired group]);

If Nothing (null in C#) is passed to the GetValidators method, all validators missing the ValidationGroup attribute set will be returned.


In our application, we are modifying the code described in Recipe 3.7 to disable the validation provided by ASP.NET by setting the CausesValidation attribute of both form-submit buttons to False.

 <input  runat="server" type="button" value="Login" CausesValidation="false" onserverclick="btnLogin_Click" validationgroup="LoginGroup" > … <input  runat="server" type="button" value="Register" CausesValidation="false" onserverclick="btnRegister_ServerClick" validationgroup="RegisterGroup" > 

In the code-behind we have added a method (groupIsValid) that will perform that validation on the group of validators defined by the passed parameter and return True if all validation for the group is valid, as shown in Examples 3-17 (VB) and 3-18 (C#).

The form-submit button event handlers will also be modified. Instead of testing the Page.IsValid property, they call the groupIsValid method with the applicable group name to determine if the data for the associated controls is valid.

When the validation provided by ASP.NET is disabled, as described in this recipe, accessing the Page.IsValid property will throw an exception indicating that Page.IsValid cannot be called before validation has taken place. Page.IsValid cannot be accessed unless Page.Validate is called either by ASP.NET or in your code.


Example 3-16. Form with programmatic validation (.aspx)

 <%@ Page Language="VB"    MasterPageFile="~/ASPNetCookbookVB.master"    AutoEventWireup="false"    CodeFile="CH03ProgrammaticValidationVB.aspx.vb"    Inherits="ASPNetCookbook.VBExamples.CH03ProgrammaticValidationVB"    title="Programmatic Validation" %> <asp:Content  Runat="server" ContentPlaceHolder> <div align="center" >    Programmatic Validation (VB) </div> <table align="center" >    </tr>   <td colspan="2" align="left">       <asp:ValidationSummary  Runat="server"    Css    DisplayMode="BulletList"    EnableClientScript="False"    HeaderText="Error Summary"    ValidationGroup="LoginGroup" /> <asp:CustomValidator  Runat="server"    Display="None"    EnableClientScript="False"    ErrorMessage="Login ID or Password Is Invalid"      OnServerValidate="cvAuthentication_ServerValidate"    ValidationGroup="LoginGroup" /> </td> </tr> </tr> <td >Login ID: </td> <td>   <asp:TextBox  Runat="server"   Columns="30" Css />   <asp:RequiredFieldValidator  Runat="server" ControlToValidate="txtLoginID" Css Display="Dynamic" EnableClientScript="False" ErrorMessage="Login ID Is Required" ValidationGroup="LoginGroup" >  <img src="/books/1/505/1/html/2/images/arrow_alert.gif" alt="arrow"/>   </asp:RequiredFieldValidator> </td> </tr> </tr> <td >Password: </td> <td>   <asp:TextBox  Runat="server"      TextMode="Password"      Columns="30" Css />   <asp:RequiredFieldValidator  Runat="server" ControlToValidate="txtPassword" Css Display="Dynamic" EnableClientScript="False" ErrorMessage="Password Is Required" ValidationGroup="LoginGroup" > <img src="/books/1/505/1/html/2/images/arrow_alert.gif" alt="arrow"/>  </asp:RequiredFieldValidator> </td> </tr> </tr> <td colspan="2" align="center"> <br/>  <input  runat="server" type="button" value="Login" causesvalidation="false" onserverclick="btnLogin_Click" validationgroup="LoginGroup" /> </td> </tr>   </table>   <hr />   <table align="center" > </tr>   <td colspan="2" align="left">  <asp:ValidationSummary  Runat="server" Css DisplayMode="BulletList" EnableClientScript="False" HeaderText="Error Summary" ValidationGroup="RegisterGroup" />   </td> </tr> </tr>   <td >Login ID: </td>   <td>      <asp:TextBox  Runat="server" Columns="30" Css />      <asp:RequiredFieldValidator      Runat="server" ControlToValidate="txtNewLoginID" Css Display="Dynamic" EnableClientScript="False" ErrorMessage="Login ID Is Required" ValidationGroup="RegisterGroup" > <img src="/books/1/505/1/html/2/images/arrow_alert.gif" alt="arrow"/>  </asp:RequiredFieldValidator>   </td> </tr> </tr>   <td >Email Address: </td>   <td>  <asp:TextBox  Runat="server" Columns="30" Css />      <asp:requiredfieldvalidator  runat="server" controltovalidate="txtEmailAddress" css display="Dynamic" enableclientscript="False" ErrorMessage="Email Address Is Required" ValidationGroup="RegisterGroup" > <img src="/books/1/505/1/html/2/images/arrow_alert.gif" alt="arrow"/>      </asp:requiredfieldvalidator>      <asp:RegularExpressionValidator      Runat="server"     ControlToValidate="txtEmailAddress"     Css     Display="Dynamic"     EnableClientScript="False" ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"     ErrorMessage="Invalid Email Address" ValidationGroup="RegisterGroup" >    <img src="/books/1/505/1/html/2/images/arrow_alert.gif" alt="arrow"/>      </asp:RegularExpressionValidator>   </td> </tr> </tr> <td >Password: </td> <td>  <asp:TextBox  Runat="server" TextMode="Password" Columns="30" Css />      <asp:RequiredFieldValidator  Runat="server" ControlToValidate="txtPassword1" Css Display="Dynamic" EnableClientScript="False" ErrorMessage="Password Is Required" ValidationGroup="RegisterGroup" >     <img src="/books/1/505/1/html/2/images/arrow_alert.gif" alt="arrow"/>      </asp:RequiredFieldValidator> </td> </tr> </tr> <td >Re-enter Password: </td> <td>      <asp:TextBox  Runat="server" TextMode="Password" Columns="30" Css />  <asp:RequiredFieldValidator  Runat="server" ControlToValidate="txtPassword2" Css Display="Dynamic" EnableClientScript="False" ErrorMessage="Re-Entered Password Is Required" ValidationGroup="RegisterGroup" >      <img src="/books/1/505/1/html/2/images/arrow_alert.gif" alt="arrow"/>  </asp:RequiredFieldValidator>      <asp:CompareValidator  runat="server" ControlToValidate="txtPassword2" ControlToCompare="txtPassword1" Css Display="Dynamic" EnableClientScript="False" ErrorMessage="Both Passwords Must Match" ValidationGroup="RegisterGroup" >       <img src="/books/1/505/1/html/2/images/arrow_alert.gif" alt="arrow"/>  </asp:CompareValidator> </td> </tr> </tr> <td colspan="2" align="center">   <br/>   <input  runat="server" type="button" value="Register" causesvalidation="false" onserverclick="btnRegister_ServerClick" validationgroup="RegisterGroup" /> </td>  </tr>   </table> </asp:Content> 

Example 3-17. Form with programmatic validation (.vb)

 Option Explicit On Option Strict On Imports System.Configuration.ConfigurationManager Imports System.Data Imports System.Data.OleDb Namespace ASPNetCookbook.VBExamples   ''' <summary>   ''' This class provides the code behind for   ''' CH03ProgrammaticValidationVB.aspx   ''' </summary>   Partial Class CH03ProgrammaticValidationVB Inherits System.Web.UI.Page '''*********************************************************************** ''' <summary> ''' This routine provides the event handler for the authentication server ''' validate event. It is responsible for checking the login ID and ''' password in the database to authenticate the user. ''' </summary> ''' ''' <param name="source">Set to the sender of the event</param> ''' <param name="args">Set to the event arguments</param> Protected Sub cvAuthentication_ServerValidate(ByVal source As Object, _ ByVal args As ServerValidateEventArgs)   Dim dbConn As OleDbConnection = Nothing   Dim dCmd As OleDbCommand = Nothing   Dim strConnection As String   Dim strSQL As String   Try 'initially assume credentials are invalid args.IsValid = False     'get the connection string from web.config and open a connection 'to the database strConnection = _ ConnectionStrings("dbConnectionString").ConnectionString dbConn = New OleDb.OleDbConnection(strConnection) dbConn.Open( ) 'build the query string and check to see if a user with the entered 'credentials exists in the database strSQL = "SELECT AppUserID FROM AppUser " & _   "WHERE LoginID=? AND " & _    "Password=?"     dCmd = New OleDbCommand(strSQL, dbConn) dCmd.Parameters.Add(New OleDbParameter("LoginID", _ txtLoginID.Text)) dCmd.Parameters.Add(New OleDbParameter("Password", _ txtPassword.Text)) 'check to see if the user was found If (Not IsNothing(dCmd.ExecuteScalar( ))) Then args.IsValid = True End If  Finally 'cleanup If (Not IsNothing(dbConn)) Then dbConn.Close( ) End If  End Try    End Sub 'cvAuthentication_ServerValidate    '''***********************************************************************    ''' <summary>    ''' This routine provides the event handler for the login button click    ''' event. It is responsible for processing the form data for login.    ''' </summary>    '''    ''' <param name="sender">Set to the sender of the event</param>    ''' <param name="e">Set to the event arguments</param>    Protected Sub btnLogin_Click(ByVal sender As Object, _  ByVal e As System.EventArgs)    'check to see if all entered login data is valid    If (groupIsValid("LoginGroup")) Then 'user has been authenticated so proceed with allowing access 'to the site    End If    End Sub 'btnLogin_Click    '''***********************************************************************    ''' <summary>    ''' This routine provides the event handler for the login button click    ''' event. It is responsible for processing the form data for    ''' registration.    ''' </summary>    '''    ''' <param name="sender">Set to the sender of the event</param>    ''' <param name="e">Set to the event arguments</param>    Protected Sub btnRegister_ServerClick(ByVal sender As Object, _   ByVal e As System.EventArgs)   'check to see if all entered registration data is valid   If (groupIsValid("RegisterGroup")) Then   'all entered data is valid so proceed with registration   End If    End Sub 'btnRegister_ServerClick    '''***********************************************************************    ''' <summary>    ''' This routine iterates through validators for the passed group    ''' performing the validation.    ''' </summary>    '''    ''' <param name="validatorGroup">Set to the name of the validator    ''' group to perform validation on.    ''' </param>    '''    ''' <returns>True if all validators in the group are valid.    '''       Else, False.    '''</returns>    Private Function groupIsValid(ByVal validatorGroup As String) As Boolean Dim validators As System.Web.UI.ValidatorCollection = Nothing Dim validator As System.Web.UI.IValidator = Nothing Dim isValid As Boolean = True 'get the validators in the Register group validators = Page.GetValidators(validatorGroup) 'iterate through the validators calling the Validate methods 'and checking to see if the validation was succcessful For Each validator In validators   validator.Validate( )   If (Not validator.IsValid) Then     isValid = False   End If Next validator Return (isValid) End Function 'groupIsValid   End Class 'CH03ProgrammaticValidationVB End Namespace 

Example 3-18. Form with programmatic validation (.cs)

 using System; using System.Configuration; using System.Data; using System.Data.OleDb; using System.Web.UI; using System.Web.UI.WebControls; namespace ASPNetCookbook.CSExamples {   /// <summary>   /// This class provides the code behind for   /// CH03ProgrammaticValidationCS.aspx   /// </summary>   public partial class CH03ProgrammaticValidationCS : System.Web.UI.Page   { ///*********************************************************************** /// <summary> /// This routine provides the event handler for the authentication server /// validate event. It is responsible checking the login ID and password /// in the database to authenticate the user. /// </summary> /// <param name="sender">Set to the sender of the event</param> /// <param name="e">Set to the event arguments</param> protected void cvAuthentication_ServerValidate(Object source, System.Web.UI.WebControls.ServerValidateEventArgs args) {   OleDbConnection dbConn = null;   OleDbCommand dCmd = null;   String strConnection = null;   String strSQL = null;   try   {     // initially assume credentials are invalid args.IsValid = false; // get the connection string from web.config and open a connection // to the database strConnection = ConfigurationManager.    ConnectionStrings["dbConnectionString"].ConnectionString; dbConn = new OleDbConnection(strConnection); dbConn.Open( ); // build the query string and check to see if a user with the // entered credentials exists in the database strSQL = "SELECT AppUserID FROM AppUser " +  "WHERE LoginID=? AND " +  "Password=?"; dCmd = new OleDbCommand(strSQL, dbConn); dCmd.Parameters.Add(new OleDbParameter("LoginID", txtLoginID.Text)); dCmd.Parameters.Add(new OleDbParameter("Password", txtPassword.Text)); // check to see if the user was found if (dCmd.ExecuteScalar( ) != null) {    args.IsValid = true; }   } // try   finally   { // cleanup if (dbConn != null) {   dbConn.Close( ); }   } // finally } // cvAuthentication_ServerValidate ///*********************************************************************** /// <summary> /// This routine provides the event handler for the login button click /// event. It is responsible for providing access to the site for the /// user if authenticated. /// </summary> /// <param name="sender">Set to the sender of the event</param> /// <param name="e">Set to the event arguments</param> protected void btnLogin_Click(Object sender, System.EventArgs e) {   // check to see if all entered login data is valid   if (groupIsValid("LoginGroup"))   { // user has been authenticated so proceed with allowing access // to the site   } } //btnLogin_Click ///*********************************************************************** /// <summary> /// This routine provides the event handler for the register button click /// event. It is responsible for processing the form data for /// registration. /// </summary> /// <param name="sender">Set to the sender of the event</param> /// <param name="e">Set to the event arguments</param> protected void btnRegister_ServerClick(Object sender, System.EventArgs e) { // check to see if all entered registration data is valid if (groupIsValid("RegisterGroup")) {   // all entered data is valid so proceed with registration } } //btnRegister_ServerClick ///*********************************************************************** /// <summary> /// This routine iterates through validators for the passed group /// performing the validation. /// </summary> /// <param name="validatorGroup">Set to the name of the validator /// group to perform validation on. /// </param> /// <returns>True if all validators in the group are valid. /// Else, False. ///</returns> private Boolean groupIsValid(String validatorGroup) {   ValidatorCollection validators = null;   Boolean isValid = true;   // get the validators in the Register group   validators = Page.GetValidators(validatorGroup);   // iterate through the validators calling the Validate methods   // and checking to see if the validation was succcessful   foreach (IValidator validator in validators)   { validator.Validate( );     if (!validator.IsValid) {    isValid = false;    } } // foreach validator   return (isValid); } // groupIsValid   } // CH03ProgrammaticValidationCS } 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2003
Pages: 202

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net