angle

ValidateUser and a tableless login form

 ASP.NET 2.0 has made it extremely easy for developers to handle the common user management tasks such as creating a new user, logging in, and changing the password. This functionality has been nicely encapsulated within server controls inlcuding the Login Control, CreateUserWizard control, and ChangePassword control. However a significant issue with these controls is that they render their content with tables. These controls do provide template regions in which one can customize the layout to a certain degree, but the controls will still wrap the region in a table.

If you are striving for a pure CSS based layout that utilizes no tables, then the option is to manually create your login form by adding a username and password field to the page. To authenticate the user the appropriate call to the Membership API must be made.

The method that is required to authenticate the user is Membership.ValidateUser. The method accepts the username and password and returns a boolean, either true if the supplied user name and password are valid; otherwise, false.

Now it's time to make a page with your custom designed login interface. Create a new page called login.aspx. Add the following code to the page.

<div><label id="lblUsername" runat="server">Username</label><asp:textbox runat="Server" id="txtUName" /></div>

<div><label id="lblPassword" runat="server">Password</label><asp:textbox runat="Server" runat="Server" id="txtPassword" textmode="Password" /></div>

<p><asp:Literal ID="ltrInvalidLogon" runat="server"></asp:Literal></p>

<asp:Button ID="btnLogin" runat="server">Login Now</asp:Button>

In the above code, we have added a textbox for the username and one for the password. A literal control is used to display an message to the user if the username and password are invalid. CSS can be used to style the above the form.  The following CSS can be used to style the form.

label
{ float: left;
text-align: right;
width: 150px;
font-size: .9em;
font-weight: bold;
margin-right: 5px;
vertical-align: text-bottom;
margin-bottom: 10px;
}

.txtboxes
{
width: 200px;
margin-bottom: 15px;
}

Set the CssClass of the asp:textbox to the .txtboxes class.

When showing such a message, dont indicate to the use which is incorrect - just show that the credentials are invalid without being specific. The button will fire the click event of the button control. Now in the codebehind for the page add the Sub that fires when the button is clicked.

Protected Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click

If (Membership.ValidateUser(txtUName.Text, txtPassword.Text)) Then FormsAuthentication.RedirectFromLoginPage(txtUName.Text, true)

Else ltrInvalidLogon.Text = "Login failed. Please check your user name and password and try again."

End If

End Sub

If the username and password are not valid, a message is displayed to the user indicating the invalid logon. Otherwise, the user is redirected to the originally requested URL by the RedirectFromLoginPage method. The RedirectFromLoginPage accepts the username and a boolean value inciating whether or not to create a persistent cookie.

One other point - <label> tags are used to identify the username and password textboxes. Clicking a label toggles the associated the textbox. However, if master pages are being used then the ID of the textboxes succumbs to the ID mangling that results when using master pages. In this case clicking a label will not place the cursor in the textbox. To make the lable work as it should, it becomes neccessary to turn it into a server control by adding and ID and the runat attribute to the label tage. Then in the Page_Load event add

lblUsername.Attributes.Add("for", txtUName.ClientID). Then do the same for the lblPassword label. Now the label tags will work as they should.
 
In this article we have examined manually calling ValidateUser when working with your own custom designed login form. By design the login page and form yourself, you gain total control over the layout and can take a CSS based approach to design. The next step involves calling ValidateUser  to authenticate a user which is an extremely easy task.