2.6.1 Problem You need to make sure the data a user enters matches an entry in a database. 2.6.2 Solution Add a CustomValidator to the .aspx file. Then add an event handler to the code-behind for the CustomValidator control's ServerValidate event, whose purpose is to validate the user entries against the database. In the .aspx file: -
Add a CustomValidator control that validates the entries against the database during server-side validation. -
Add a Login (or equivalently named) button. In the code-behind class for the page, use the .NET language of your choice to: -
Add an event handler for the CustomValidator control's ServerValidate event whose purpose is to provide the server-side validation of the user's entries against the database. -
Add code to the event handler for the Login button's click event to check the Page.IsValid property and verify that all validation was successful (see Recipe 2.1 for details). Figure 2-11 shows a typical form with normal output prior to data entry. Figure 2-12 shows the form with a validation error message. Example 2-10 through Example 2-12 show the .aspx and code-behind files for our application that implements the solution. Figure 2-11. Form with database validation output ”normal Figure 2-12. Form with database validation output ”with error message 2.6.3 Discussion One of the most common examples of when this recipe comes in handy is when implementing a classic login page. The approach we favor in this scenario uses a CustomValidator to perform the user authentication and a ValidationSummary to display error information. In our example, RequiredFieldValidator controls are used for the login ID and password fields. (RequiredFieldValidator controls are described in Recipe 2.1.) The user must supply both to gain access to her account. Unlike the other recipes in this chapter, our approach for this recipe has the CustomValidator control's EnableClientScript attribute set to False to disable client-side validation because the database validation can be done only on the server side: <asp:CustomValidator id="cvAuthentication" Runat="server" Display="None" EnableClientScript="False" ErrorMessage="Login ID or Password Is Invalid" /> The ValidationSummary is set up to display all validation errors. This includes errors from the RequiredFieldValidator controls and the CustomValidator used for user authentication. The ServerValidate event for the CustomValidator ( cvAuthentication_ServerValidate ) is used to perform the user authentication by checking to see if a user exists in the database with the entered login ID and password, as shown in Example 2-11 (VB) and Example 2-12 (C#). If the user is found in the database, the args.IsValid property is set True to indicate the validation was successful. Otherwise, it is set False to indicate the validation failed. The event handler for the Login button's click event ( btnLogin_Click ) then checks to see if the page is valid before proceeding with actions required to log the user into the system. As you may have noticed, the approach used in this recipe is an amalgam of all the approaches used in the chapter's other recipes. Having used this approach to control essentially all the aspects of validation, you can now adapt it to perform virtually any validation your application requires. 2.6.4 See Also Recipe 2.1; Recipe 2.5 Example 2-10. Form with database validation (.aspx) <%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH02CustomDatabaseValidationVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH02CustomDatabaseValidationVB" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Custom Database Validation</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmValidation" method="post" runat="server"> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center" class="PageHeading"> Custom Database Validation (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center"> <table border="0"> <tr> <td colspan="2" align="left"> <asp:ValidationSummary id="vsErrors" Runat="server" CssClass="AlertText" DisplayMode="BulletList" EnableClientScript="True" HeaderText="Error Summary" /> <asp:CustomValidator id="cvAuthentication" Runat="server" Display="None" EnableClientScript="False" ErrorMessage="Login ID or Password Is Invalid" /> </td> </tr> <tr> <td class="LabelText">Login ID: </td> <td> <asp:TextBox id="txtLoginID" Runat="server" Columns="30" CssClass="LabelText" /> <asp:RequiredFieldValidator id="rfvLoginID" Runat="server" ControlToValidate="txtLoginID" CssClass="AlertText" Display="Dynamic" EnableClientScript="True" ErrorMessage="Login ID Is Required"> <img src="images/arrow_alert.gif"> </asp:RequiredFieldValidator> </td> </tr> <tr> <td class="LabelText">Password: </td> <td> <asp:TextBox id="txtPassword" Runat="server" TextMode="Password" Columns="30" CssClass="LabelText" /> <asp:RequiredFieldValidator id="rfvPassword" Runat="server" ControlToValidate="txtPassword" CssClass="AlertText" Display="Dynamic" EnableClientScript="True" ErrorMessage="Password Is Required"> <img src="images/arrow_alert.gif"> </asp:RequiredFieldValidator> </td> </tr> <tr> <td colspan="2" align="center"> <br> <asp:ImageButton id="btnLogin" Runat="server" CausesValidation="True" ImageUrl="images/buttons/button_login.gif" /> </td> </tr> </table> </td> </tr> </table> </form> </body> </html> Example 2-11. Form with database validation code behind (.vb) Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH02CustomDatabaseValidationVB.aspx.vb ' ' Description: This module provides the code behind for ' CH02CustomDatabaseValidationVB.aspx ' '***************************************************************************** Imports Microsoft.VisualBasic Imports System.Configuration Imports System.Data Imports System.Data.OleDb Imports System.Web.UI.WebControls Namespace ASPNetCookbook.VBExamples Public Class CH02CustomDatabaseValidationVB Inherits System.Web.UI.Page 'controls on form Protected WithEvents cvAuthentication As CustomValidator Protected txtLoginID As TextBox Protected txtPassword As TextBox Protected WithEvents btnLogin As ImageButton '************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load If (Not Page.IsPostBack) Then 'Put user code to initialize the page here End If End Sub 'Page_Load '************************************************************************* ' ' ROUTINE: cvAuthentication_ServerValidate ' ' DESCRIPTION: 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. '------------------------------------------------------------------------- Private Sub cvAuthentication_ServerValidate(ByVal source As Object, _ ByVal args As ServerValidateEventArgs) _ Handles cvAuthentication.ServerValidate Dim dbConn As OleDbConnection Dim dCmd As OleDbCommand 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 = _ ConfigurationSettings.AppSettings("dbConnectionString") 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 '************************************************************************* ' ' ROUTINE: btnLogin_Click ' ' DESCRIPTION: This routine provides the event handler for the login ' button click event. It is responsible for processing ' the form data. '------------------------------------------------------------------------- Private Sub btnLogin_Click(ByVal sender As Object, _ ByVal e As System.Web.UI.ImageClickEventArgs) _ Handles btnLogin.Click If (Page.IsValid) Then 'user has been authenticated so proceed with allowing access 'to the site End If End Sub 'btnLogin_Click End Class 'CH02CustomDatabaseValidationVB End Namespace Example 2-12. Form with database validation code behind (.cs) //---------------------------------------------------------------------------- // // Module Name: CH02CustomDatabaseValidationCS.aspx.cs // // Description: This module provides the code behind for // CH02CustomDatabaseValidationCS.aspx // //**************************************************************************** using System; using System.Configuration; using System.Data; using System.Data.OleDb; using System.Web.UI; using System.Web.UI.WebControls; namespace ASPNetCookbook.CSExamples { public class CH02CustomDatabaseValidationCS : System.Web.UI.Page { // controls on form protected CustomValidator cvAuthentication; protected TextBox txtLoginID; protected TextBox txtPassword; protected ImageButton btnLogin; //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { // wire the login button click and the authentication validation events this.btnLogin.Click += new ImageClickEventHandler(this.btnLogin_Click); this.cvAuthentication.ServerValidate += new ServerValidateEventHandler(this.cvAuthentication_ServerValidate); if (!Page.IsPostBack) { //Put user code to initialize the page here } } // Page_Load //************************************************************************ // // ROUTINE: cvAuthentication_ServerValidate // // DESCRIPTION: 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. //------------------------------------------------------------------------ private 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 = ConfigurationSettings.AppSettings["dbConnectionString"]; 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 //************************************************************************ // // ROUTINE: btnLogin_Click // // DESCRIPTION: This routine provides the event handler for the save // button click event. It is responsible for processing // the form data. //------------------------------------------------------------------------ private void btnLogin_Click(Object sender, System.Web.UI.ImageClickEventArgs e) { if (Page.IsValid) { // user has been authenticated so proceed with allowing access // to the site } } // btnLogin_Click } // CH02CustomDatabaseValidationCS } |