December 2001
 |
Encapsulate Web Forms Code Learn how to create Web user controls that handle login checking for your .NET Web pages. by Stan SchultesTechnology Toolbox VB.NET, SQL Server 2000, ASP.NET, Windows 2000 Server for Web server, Workstation for development
Note: Also works with SQL Server 7.0 and Access 97/2000/XP |
The .NET environment's most useful category of new technology is arguably its Web development tools, especially the Web Forms technology. Web Forms incorporates the event-driven programming model that Visual Basic made popular. You can now build a Web app with event routines that respond to actions a user makes on a Web page, much as you would with a traditional VB program. I'll show you how to build a pair of Web user controls to add custom login functionality to your .NET Web applications. Web user controls are reusable bits of Web page functionality that you build into a special class file with an ASCX extension. Essentially, these controls are the contents of a Web form without the opening and closing form tags (<form> and </form>), which are part of the Web Forms page itself. You drop the user control onto a Web form, and it becomes a subset of the form's functionality. The sample code for this column consists of two Web user controls: loginCheck and loginControl. The loginCheck control is an invisible control that checks whether the user has logged in and if not, it redirects the user to the login page; you place the control on any Web page you want to protect with a user login. The loginControl Web control provides the user interface for your login page and allows access to the protected page once the user logs in successfully. You choose from two login modes with loginControlby e-mail address with a common password (the same for everyone logging in), or by username with a private password you assign to each user in advance. Start by running the VS.NET Integrated Development Environment (IDE). You can build any .NET project without the IDE, but for this project, I'll assume you have VS.NET. If you've never used VS.NET before, you'll begin at the Start page, which allows you to customize your VS profile by setting the keyboard scheme, screen layout, and other startup options. If you're a VB6 programmer, you might want to choose the VB6 keyboard layout and use the Visual Studio default window layout. After you set your options, choose the Get Started link from the list in the blue bar on the left side, then click on the New Project button. Select Visual Basic as the project type, choose the ASP.NET Web Application icon from the Templates list, and name your project PasswordProtect. Type your Web server address in the Location textbox (you can use http://localhost for your local Web server). When you click on the OK button, VS.NET creates a virtual directory for you and adds project files. See the code download's readme file for additional details if you want to load the sample code. Build the Sample Application
The sample application consists of a default page (default.aspx), an unprotected page (public.htm), a protected page (privatePage.aspx), and a login page (login.aspx). Rename the default WebForm1.aspx to default.aspx, then right-click on the PasswordProtect project item in the Solution Explorer and choose Add | Add Web Form for the other two ASPX pages. Pick the Web Form template and name each file as I described. Choose Add | Add HTML Page for public.htm, and choose the HTML Page template.
Add hyperlinks to link each page to the others, except for the login pageyou'll use a redirect to that page. Test your page navigation by pressing F5 to build and run, and follow each of your links. At this point, you should be able to reach the protected page without a login. Close the browser window to stop the debugger. Create the loginCheck control by right-clicking on the PasswordProtect project item in the Solution Explorer and choosing Add | Add Web User Control. Select the Web User Control template and change the control's name to loginCheck.ascx. The loginCheck control has no user interface, so you'll ignore the loginCheck form designer in this case. Right-click on the loginCheck item in the Solution Explorer and choose View Code to see the contents of the loginCheck.ascx.vb file. This is known as the code-behind file for the loginCheck.ascx Web control. The loginCheck control has two properties: a flag for enabling or disabling logins on the page it protects, and the page's URL to use for logins. Add two variables at class scope (near the top of the file) to hold the property values:
Private m_sLoginPageURL As String = _
"Login.aspx"
Private m_bEnabled As Boolean = True You assign default values to the properties at variable declaration time. Create property procedures using the new property syntax:
'page to redirect to for login
Public Property LoginPageURL() As _
String
Get
Return m_sLoginPageURL
End Get
Set(ByVal Value As String)
m_sLoginPageURL = Value
End Set
End PropertyThe login controls also use several "global" values that are kept in Session variables for convenience. Add these variables to the Global.asax.vb file (right-click on Global.asax in the Solution Explorer and choose View Code):
Sub Session_OnStart()
'Login authentication configuration
'choices for LoginType: email, user
Session("LoginType") = "email"
Session("LoginUser") = "Master"
Session("LogVisits") = True
End SubAlso, a database control setting is stored in the Application("DBType") variable in Global.asax.vb. The sample code includes both a SQL Server script defining the database tables, as well as an empty Access 2000 database. See the readme file for information on configuring the login database. In the loginCheck.ascx.vb source file, find the Page_Load event routine and add code to handle the login validation process (see Listing 1). A Web user control's Page_Load event is fired when the control is rendered on its ASPX page, after the page's Page_Load event is fired. If the user hasn't already successfully logged into the page protected by loginCheck, the page redirects to the specified login page for validation. If the user has logged in already and the SessionID hasn't expired (the default session timeout is 20 minutes), loginCheck passes the user directly to the protected page. Protect Your Pages
Drop the loginCheck.ascx control only on the pages you want users to access by login. Open your protected page's designer by double-clicking on the privatePage.aspx item in the Solution Explorer. Drag the loginCheck control from the Solution Explorer list and drop it onto the privatePage designer. The loginCheck control is invisible at run time, so it doesn't matter where you drop it on the form.
Open privatePage.aspx's code-behind page by double-clicking on the form designer. You must add references in the Web form code manually to access user controls you place on Web forms. Add a declaration at the top of the privatePage class:
Public Class privatePage
Inherits System.Web.UI.Page
Protected LoginCheck1 As loginCheck
'<other code omitted>
End Class In the Page_Load event, add this code to initialize the loginCheck control:
Private Sub Page_Load _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
LoginCheck1.Enabled = True
LoginCheck1.LoginPageURL = _
"Login.aspx"
End SubHere you enable or disable login checking and define which page handles the login on a page-by-page basis. Run the project again and navigate to the protected page; you're redirected to the login page, which is still blank at this point. Create another Web user control in the PasswordProtect project and name it loginControl.ascx. Double-click on the loginControl item in the Solution Explorer to open its UI designer. Unlike loginCheck, loginControl has a UI consisting of labeled username and password textboxes, a Login button, a label to report login failures, and several validation controls (see Figure 1). All these controls come from the Web Forms tab on the toolbox. You arrange them into a table on the designer to keep the controls together when you drop the user control onto a Web page. The textboxes, button, and labels work as you would expect in any VB application, and each can fire events on the Web server. The validation controls, new to VB.NET, provide intelligent client-side input validation for browsers that support JavaScript. For "down-level" browsers (those that don't support JavaScript), validation occurs automatically on the server side, requiring a round trip for each validation operation. You use three validation controls and a Validation Summary control in PasswordProtect. The username and password text input fields each need a Required Field Validation (RFV) control to ensure the user enters a value. When the login mode is set to email, the username field also needs a Regular Expression Validation (REV) control to ensure the user input conforms to an e-mail address pattern. From the Web Forms tab on the toolbox, place an REV control on the designer next to the username textbox. Set the Text property to an asterisk (*), which is what you see at the validation control's form location when validation fails. Set the ControlToValidate property to the username textbox and the ErrorMessage property to "Enter the email address as: user@domain." For the ValidationExpression property, choose Internet Email Address from the Standard Expressions list. Finally, set the REV control's Display property to Dynamic because it shares the space with an RFV control on the same username textbox. Set up the two RFV controls in a similar manner. Place the Validation Summary control below the other controls in the tableit displays the error text from each of the three validation controls automatically when the user makes an entry error. Set up the Page_Load event routine in loginControl.ascx.vb to initialize the user controls based on the application's validation mode: email or user (see Listing A). On the loginControl.ascx designer, double-click on the Login button to open its Click event routine. A user click on the Login button fires the Click event on the Web server after successful field validation. Add code to grab the form control values and check the login credentials against the database (see Listing 2). The CheckPass routine contains the ADO.NET code to query the database and check the login (see Listing B). Once the login succeeds, the routine places the password in a Session variable named login-page_valid. For example, if you use the login.aspx page for login validation, you use the variable Session("login.aspx_valid"). This allows you to have different passwords for different login pages. The sample code also contains a LogVisit function to write database entries as users log into your protected pages. You control visit logging with the Session("LogVisits") value from Global.asax.vb. To set up the login form, open the login.aspx designer by double-clicking on it in the Solution Explorer. Drag the loginControl from the Solution Explorer and drop it on the login page designer, placing it in the location you'd like the Web control's UI to appear. The login page doesn't need any other codeall the login functionality resides in the loginControl user control. Don't forget to declare the user control in the form if you want to use it in code. Run the project, navigate to the protected page, and test the login form's validation controls and login code. Web user controls offer a convenient way of encapsulating common portions of Web Forms code for easy reuse. With a little thought, you can save yourself and your team lots of time by creating useful Web user controls you can use on all your Web pages. For practice, allow users to maintain their own passwords, and add a user self-registration mode to the login controls in the PasswordProtect application. About the Author Stan Schultes is a project and IT manager, and a VB/Web enterprise application architect and developer in Sarasota, Fla. Stan is an MCP in VB and spoke on VB development at Microsoft's DevDays conference. He is also a contributing editor and regular author for VSM. Reach Stan at stan@vbexpert.com. |