Using the Login Controls

You can use the ASP.NET Login controls to easily build a user registration system for your website. You can use the Login controls to display user registration forms, login forms, change password forms, and password reminder forms. By default, the Login controls use ASP.NET Membership to authenticate  Users, create new users, and change user properties. When you use the Login controls, you are not required to write any code when performing these tasks. ASP.NET Membership is discussed in detail in the following chapter. In the first part of this chapter, you are provided with an overview of the Login controls. You learn how to passwordprotect a section of your website and enable users to register and log in to your website. In the remainder of this chapter, you learn how to use each of the following Login controls in detail:
  • Login—Enables you to display a user login form.
  • CreateUserWizard—Enables you to display a user registration form.
  • LoginStatus—Enables you to display either a log in or log out link, depending on a user’s authentication status.
  • LoginName—Enables you to display the current user’s registered username.
  • ChangePassword—Enables you to display a form that allows users to change their passwords.
  • PasswordRecovery—Enables you to display a form that allows a user to receive an email containing his or her password.
  • LoginView—Enables you to display different content to different users depending on the user’s authentication status or role.
Overview of the Login Controls
You won’t have any fun using the Login controls unless you have confidential information to protect. Therefore, let’s start by creating a page that needs password protection. Create a new folder in your application named SecretFiles and add the page. to the SecretFiles folder.

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Secret</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<h1>This Page is Secret!</h1>
</div>
</form>
</body>
</html>

There is nothing special about the page in Listing. It just displays the message This Page is Secret!. To password-protect the Secret.aspx page, you need to make two configuration changes to your application: You need to configure both authentication and authorization. First, you need to enable the proper type of authentication for your application. By default, Windows authentication is enabled. To use the Login controls, you need enable

Forms authentication by adding the web configuration file in Listing  to the root of your application.

<configuration>
<system.web>
<authentication mode=”Forms” />
</system.web>
</configuration>

The web configuration file in Listing contains an authentication element that includes a mode attribute. The mode attribute has the value Forms. By default, all users have access to all pages in an application. If you want to restrict access to the pages in a folder, then you need to configure authorization for the folder. If you add the web configuration file in Listing to the SecretFiles folder, then anonymous users are prevented from accessing any pages in the folder.

<configuration>
<system.web>
<authorization>
<deny users=”?”/>
</authorization>
</system.web>
</configuration>

The web configuration file in Listing contains an authorization element. This element contains a list of authorization rules for the folder. The single authorization rule in Listing prevents anonymous users from accessing pages in the folder. (The ? represents anonymous users.) If you prefer, you can use the Web Site Administration Tool to configure authentication and authorization. This tool provides you with a form interface for performing these  configuration changes. When using Visual Web Developer, you can open the Web Site Administration Tool by selecting the menu option Website, ASP.NET Configuration.

If you attempt to request the Secret.aspx page after adding the web configuration file in Listing, then you are redirected to a page named Login.aspx automatically. Therefore, the next page that we need to create is the Login.aspx page. (By default, this page must be located in the root of your application.) The Login.aspx page in Listing contains a Login control. The Login control automatically generates a login form.

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Login</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:Login id=”Login1” CreateUserText=”Register” CreateUserUrl=”~/Register.aspx” Runat=”server” />
</div>
</form>
</body>
</html>

Notice that the Login control includes a CreateUserText and CreateUserUrl property. Adding these properties to the Login control causes the control to display a link to a page that enables a new user to register for your application. The Login control in Listing links to a page named Register.aspx. This page is contained in Listing.

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Register</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:CreateUserWizard id=”CreateUserWizard1”
ContinueDestinationPageUrl=”~/SecretFiles/Secret.aspx” Runat=”server” />
</div>
</form>
</body>
</html>

The Register.aspx page contains a CreateUserWizard control. This control automatically generates a user registration form. After you submit the form, a new user is created, and you are redirected back to the Secret.aspx page.

The default ASP.NET Membership provider requires you to create a password that contains at least seven characters, and at least one of the characters must be nonalphanumeric (not a letter and not a number). So, secret_ is a valid password, but not secret9.

In the next chapter, you learn how to change these default passwords requirements. That’s all there is to it. Notice that we have created a complete user registration system without writing a single line of code. All the messy details of storing usernames and passwords are taken care of by the ASP.NET Framework in the background.

Using the Login Control
The Login control renders a standard user login form. By default, the Login control uses ASP.NET Membership to authenticate users. However, as you’ll see in a moment, you can customize how the Login control authenticates users. The Login control supports a large number of properties that enable you to customize the appearance and behavior of the control (too many properties to list here). The page in Listing illustrates how you can modify several of the Login control’s properties to customize the form rendered by the control.
 <%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<style type=”text/css”>
.login
{
width:250px;
font:14px Verdana,Sans-Serif;
background-color:lightblue;
border:solid 3px black;
padding:4px;
}
.login_title
{
background-color:darkblue;
color:white;
font-weight:bold;
}
.login_instructions
{
font-size:12px;
text-align:left;
padding:10px;
}
.login_button
{
border:solid 1px black;
padding:3px;
}
</style>
<title>Show Login</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:Login id=”Login1” InstructionText=”Please log in before accessing the premium section of our Website.” TitleText=”Log In” TextLayout=”TextOnTop” LoginButtonText=”Log In”
DisplayRememberMe=”false” CssClass=”login” TitleTextStyle-CssClass=”login_title”
InstructionTextStyle-CssClass=”login_instructions” LoginButtonStyle-CssClass=”login_button”
Runat=”server” />
</div>
</form>
</body>
</html>

The page in Listing uses Cascading Style Sheets to change the appearance of the login form rendered by the Login control. By taking advantage of Cascading Style Sheets, you can customize the appearance of the Login control in any way that you can imagine. For the complete list of properties supported by the Login control, see the Microsoft .NET Framework SDK documentation.

Automatically Redirecting a User to the Referring Page
If you request a page that you are not authorized to view, then the ASP.NET Framework automatically redirects you to the Login.aspx page. After you log in successfully, you are redirected back to the original page that you requested. When you are redirected to the Login.aspx page, a query string parameter named ReturnUrl is automatically added to the page request. This query string parameter contains the path of the page that you originally requested. The Login control uses the ReturnUrl parameter when redirecting you back to the original page.

You need to be aware of two special circumstances. First, if you request the Login.aspx page directly, then a ReturnUrl parameter is not passed to the Login.aspx page. In that case, after you successfully log in, you are redirected to the Default.aspx page.

Second, if you add the Login control to a page other than the Login.aspx page, then the ReturnUrl query string parameter is ignored. In this case, you need to set the Login control’s DestinationPageUrl property. When you successfully log in, you are redirected to the URL represented by this property. If you don’t supply a value for the DestinationPageUrl property, the same page is reloaded.

Automatically Hiding the Login Control from Authenticated Users
Some websites display a login form at the top of every page. That way, registered users can log in at any time to view additional content. The easiest way to add a Login control to all the pages in an application is to take advantage of Master Pages. If you add a Login control to a Master Page, then the Login control is included in every content page that uses the Master Page.

You can change the layout of the Login control by modifying the Login control’s Orientation property. If you set this property to the value Horizontal, then the Username and Password text boxes are rendered in the same row. If you include a Login control in all your pages, you should also modify the Login control’s VisibleWhenLoggedIn property. If you set this property to the value False, then the Login control is not displayed when a user has already authenticated.

Using a Template with the Login Control
If you need to completely customize the appearance of the Login control, then you can use a template. The Login control includes a LayoutTemplate property that enables you to customize the layout of the controls rendered by the Login control. When you create a Layout template, you can add controls to the template that have the following IDs:

. UserName
. Password
. RememberMe
. FailureText

You also need to add a Button control that includes a CommandName property with the value Login.

Performing Custom Authentication with the Login Control
By default, the Login control uses ASP.NET Membership to authenticate a username and password. If you need to change this default behavior, then you can handle the Login control’s Authenticate event. Imagine, for example, that you are building a simple application and you want to store a list of usernames and passwords in the web configuration file. The web configuration file in Listing 22.10 contains the credentials for two users named Bill and Ted.

<configuration>
<system.web>
<authentication mode=”Forms”>
<forms>
<credentials passwordFormat=”Clear”>
<user name=”Bill” password=”secret” />
<user name=”Ted” password=”secret” />
</credentials>
</forms>
</authentication>
</system.web>
</configuration>

The page in Listing contains a Login control that authenticates users against the list of usernames and passwords stored in the web configuration file.
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
string userName = Login1.UserName;
string password = Login1.Password;
e.Authenticated = FormsAuthentication.Authenticate(userName, password);
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Login Custom</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:Login id=”Login1” OnAuthenticate=”Login1_Authenticate” Runat=”server” />
</div>
</form>
</body>
</html>

Notice that the page in Listing includes a method that handles the Login control’s Authenticate event. The second parameter passed to the Authenticate event handler is an instance of the AuthenticateEventArgs class. This class includes the following property:
  • Authenticated

If you assign the value True to this property, then the Login control authenticates the user. In Listing, the FormsAuthentication.Authenticate() method is called to check for a username and password in the web configuration file that matches the username and password entered into the login form. The value returned from this method is assigned to the AuthenticateEventArgs.Authenticated property.

Using the CreateUserWizard Control
The CreateUserWizard control renders a user registration form. If a user successfully submits the form, then a new user is added to your website. In the background, the CreateUserWizard control uses ASP.NET membership to create the new user. The CreateUserWizard control supports a large number of properties (too many to list here) that enables you to modify the appearance and behavior of the control. For example, the page in Listing uses several of the CreateUserWizard properties to customize the appearance of the form rendered by the control.


<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<style type=”text/css”>
.createUser
{
width:350px;
font:14px Verdana,Sans-Serif;
background-color:lightblue;
border:solid 3px black;
padding:4px;
}
.createUser_title
{
background-color:darkblue;
color:white;
font-weight:bold;
}
.createUser_instructions
{
font-size:12px;
text-align:left;
padding:10px;
}
.createUser_button
{
border:solid 1px black;
padding:3px;
}
</style>
<title>Show CreateUserWizard</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:CreateUserWizard id=”CreateUserWizard1” ContinueDestinationPageUrl=”~/Default.aspx”
InstructionText=”Please complete the following form to register at this Website.”
CompleteSuccessText=”Your new account has been created. Thank you for registering.”
CssClass=”createUser” TitleTextStyle-CssClass=”createUser_title”
InstructionTextStyle-CssClass=”createUser_instructions”
CreateUserButtonStyle-CssClass=”createUser_button”
ContinueButtonStyle-CssClass=”createUser_button” Runat=”server” />
</div>
</form>
</body>
</html>

The CreateUserWizard control in Listing s formatted with Cascading Style Sheets. Notice that the control’s ContinueDestinationPageUrl property is set to the value ”~/Default.aspx”.

After you successfully register, you are redirected to the Default.aspx page. For the complete list of properties supported by the CreateUserWizard control, see the Microsoft .NET Framework SDK documentation.

Configuring Create User Form Fields
By default, the CreateUserWizard control displays the following form fields:

. Username
. Password
. Confirm Password
. Email
. Security Question
. Security Answer

These are the default form fields. The last three fields are optional. If you don’t want to require a user to enter either an email address or a security question and answer, then you need to modify the configuration of the default membership provider.
<configuration>
<system.web>
<authentication mode=”Forms” />
<membership defaultProvider=”MyMembership”>
<providers>
<add name=”MyMembership” type=”System.Web.Security.SqlMembershipProvider”
connectionStringName=”LocalSqlServer” requiresQuestionAndAnswer=”false”
requiresUniqueEmail=”false” />
</providers>
</membership>
</system.web>
</configuration>

If you add the web configuration file in Listing to your application, then the CreateUserWizard control does not render fields for a security question and answer. However, the CreateUserWizard control still renders an email field. If you don’t want the email form field to be rendered, then you must perform an additional step. You must set the CreateUserWizard control’s RequireEmail property to the value False.
If you add the page in Listing to an application that contains the web configuration file in Listing, then the email, security question, and security answer form fields are not displayed.

 <%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>CreateUserWizard Short</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:CreateUserWizard id=”CreateUserWizard1” RequireEmail=”false” Runat=”server” />
</div>
</form>
</body>
</html>

Don’t set the CreateUserWizard control’s RequireEmail property to the value False when the membership provider’s requiresUniqueEmail property is set to the value True. In other words, don’t require an email address when you haven’t provided a user with a method for entering an email address.

Sending a Create User Email Message
You can set up the CreateUserWizard control so that it automatically sends an email when a new user registers. For example, you can send an email that contains the new user’s registered username and password to that user’s email account.

Sending an unencrypted email across the Internet with a user’s password is dangerous. However, it also is a very common practice to include a password in a registration confirmation email. The page in Listing includes a MailDefinition property that specifies the properties of the email that is sent to a user after the user successfully registers. 


<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>CreateUserWizard Email</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:CreateUserWizard id=”CreateUserWizard1” Runat=”server”>
<MailDefinition BodyFileName=”Register.txt” Subject=”Registration Confirmation”
From=”Admin@YourSite.com” />
</asp:CreateUserWizard>
</div>
</form>
</body>
</html>

The MailDefinition class supports the following properties:
  • BodyFileName—Enables you to specify the path to the email message.
  • CC—Enables you to send a carbon copy of the email message.
  • EmbeddedObjects—Enables you to embed objects, such as images, in the email message.
  • From—Enables you to specify the FROM email address.
  • IsBodyHtml—Enables you to send an HTML email message.
  • Priority—Enables you to specify the priority of the email message. Possible values are High, Low, and Normal.
  • Subject—Enables you to specify the subject of the email message.

The MailDefinition associated with the CreateUserWizard control in Listing sends the contents of the text file in Listing.

`Thank you for registering!
Here is your new username and password:
username: <% UserName %>
password: <% Password %>

Notice that the email message in Listing includes two special expressions: <% UserName %> and <% Password %>. When the email is sent, the user’s registered username and password are substituted for these expressions.

You can send a user’s password in an email message even when password is encrypted or hashed by the Membership provider. The MailDefinition class uses the email server configured by the smtp element in the web configuration file. For example, the web configuration file in Listing illustrates how FIGURE  Receiving a registration email. you can configure the MailDefinition class to use the local SMTP server included with Internet Information Services. (You can enable the local SMTP Server by opening Internet
Information Services from the Administrative Tools folder.)

<configuration>
<system.net>
<mailSettings>
<smtp deliveryMethod=”PickupDirectoryFromIis”/>
</mailSettings>
</system.net>
<system.web>
<authentication mode=”Forms” />
</system.web>
</configuration>

Automatically Redirecting a User to the Referring Page
When you successfully log in from the Login.aspx page, you automatically are redirected back to the original page you requested. The CreateUserWizard control, on the other hand, does not redirect you back anywhere. If you want the CreateUserWizard control to work in the same way as the Login control, you need to write some code. The Login control in Listing includes a link to a user registration page named CreateUserWizardReturn.aspx. In the Page_Load() event handler, the value of the ReturnUrl query string parameter is added to the link to the registration page.

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string dest = Request.QueryString[“ReturnUrl”];
Login1.CreateUserUrl = “~/CreateUserWizardReturn.aspx?ReturnUrl=” +
Server.UrlEncode(dest);
}
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Login Return</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:Login id=”Login1” CreateUserText=”Register” CreateUserUrl=”~/CreateUserWizardReturn.aspx”
Runat=”server” />
</div>
</form>
</body>
</html>

Before you use the page in Listing, you need to rename the page to Login.aspx. If a user requests a page that the user is not authorized to access, then the user is automatically redirected to the Login.aspx page. The ReturnUrl parameter is automatically added to the request for Login.aspx. The page in Listing contains a CreateUserWizard control. This page also contains a Page_Load() event handler. The value of the ReturnUrl query string parameter is used to redirect the user back to the originally requested page.

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
void Page_Load()
{
if (!Page.IsPostBack)
{
string dest = “~/Default.aspx”;
if (!String.IsNullOrEmpty(Request.QueryString[“ReturnURL”]))
dest = Request.QueryString[“ReturnURL”];
CreateUserWizard1.ContinueDestinationPageUrl = dest;
}
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>CreateUserWizard Return</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:CreateUserWizard id=”CreateUserWizard1” Runat=”server” />
</div>
</form>
</body>
</html>

Automatically Generating a Password
Some websites require you to complete multiple steps when registering. For example, you must complete the following steps when registering for a new account at eBay:

1. Complete the registration form.
2. Receive an email with a confirmation code.
3. Enter the confirmation code into a form.

This method of registration enables you to verify a user’s email address. If someone enters an invalid email address, then the confirmation code is never received. If you need to implement this registration scenario, then you need to know about the following three properties of the CreateUserWizard control:
  • AutoGeneratePassword—Enables the CreateUserWizard control to generate a new password automatically.
  • DisableCreatedUser—Enables you to disable the new user account created by the CreateUserWizard control.
  • LoginCreatedUser—Enables you to prevent a new user from being logged in automatically.


You can send two types of confirmation email messages. First, you can generate a new password automatically and send the password to the user. In that case, you’ll want to enable the AutoGeneratePassword property and disable the LoginCreatedUser properties. Alternatively, you can allow a new user to enter her own password and send a distinct confirmation code in the confirmation email message. In that case, you’ll want to enable the DisableCreatedUser property and disable the LoginCreatedUser property. Let’s examine each of these scenarios in turn. The page in Listing contains a CreateUserWizard control that does not render a password form field. The control has its AutoGeneratePassword property enabled and its LoginCreatedUser property disabled. After you complete the form rendered by the CreateUserWizard control, you can click the Continue button to open the Login.aspx page.

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>CreateUserWizard Password Confirmation</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:CreateUserWizard id=”CreateUserWizard1” CompleteSuccessText=”A confirmation email
containing your new password has been sent to your email address.”
AutoGeneratePassword=”true” LoginCreatedUser=”false” ContinueDestinationPageUrl=”~/Login.aspx”
Runat=”server”>
<MailDefinition From=Admin@YourSite.com BodyFileName=”PasswordConfirmation.htm”
IsBodyHtml=”true” Subject=”Registration Confirmation” />
</asp:CreateUserWizard>
</div>
</form>
</body>
</html>

Don’t set the membership provider’s passwordStrengthRegularExpression attribute when enabling the CreateUserWizard control’s AutoGeneratePassword property. The CreateUserWizard control in Listing sends the email message contained.

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head>
<title>Password Confirmation</title>
</head>
<body>
Your new password is <% Password %>.
</body>
</html>

The email message in Listing includes the automatically generated password. Whenthe new user receives the automatically generated password in her inbox, she can enter the password in the Login.aspx page.

In the second scenario, the user gets to choose his password. However, the user’s account is disabled until he enters his confirmation code. The CreateUserWizard control in Listing has its DisableCreateUser property enabled and its LoginCreatedUser property disabled.

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
protected void CreateUserWizard1_SendingMail(object sender,MailMessageEventArgs e)
{
MembershipUser user = Membership.GetUser(CreateUserWizard1.UserName);
string code = user.ProviderUserKey.ToString();
e.Message.Body = e.Message.Body.Replace(“<%ConfirmationCode%>”, code);
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>CreateUserWizard Code Confirmation</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:CreateUserWizard id=”CreateUserWizard1”
CompleteSuccessText=”A confirmation email containing your new password has been sent to your email address.” DisableCreatedUser=”true” ContinueDestinationPageUrl=”~/ConfirmCode.aspx”
OnSendingMail=”CreateUserWizard1_SendingMail” Runat=”server”>
<MailDefinition From=Admin@YourSite.com BodyFileName=”CodeConfirmation.htm”
IsBodyHtml=”true” Subject=”Registration Confirmation” />
</asp:CreateUserWizard>
</div>
</form>
</body>
</html>

Notice that the page in Listing includes a SendingMail event handler. The confirmation code is the unique key assigned to the new user by the membership provider (a GUID). The confirmation code is substituted into the email message before the message is sent. The email message is contained in Listing.

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head>
<title>Code Confirmation</title>
</head>
<body>
<%UserName%>,
your confirmation code is <%ConfirmationCode%>
</body>
</html>

After you complete the form rendered by the CreateUserWizard control, you can click the
Continue button to open the ConfirmCode.aspx page.

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
protected void btnConfirm_Click(object sender, EventArgs e)
{
MembershipUser user = Membership.GetUser(txtUserName.Text);
if (user == null)
{
lblError.Text = “Invalid User Name”;
}
else
{
string providerCode = user.ProviderUserKey.ToString();
string userCode = txtConfirmationCode.Text.Trim();
if (providerCode != userCode)
{
lblError.Text = “Invalid Confirmation Code”;
}
else
{
user.IsApproved = true;
Membership.UpdateUser(user);
Response.Redirect(“~/SecretFiles/Secret.aspx”);
}
}
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Confirm Code</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<p>
Enter the confirmation code that you received by email.
</p>
<asp:Label id=”lblError” EnableViewState=”false” ForeColor=”Red” Runat=”server” />
<br /><br />
<asp:Label id=”lblUserName” Text=”User Name:” AssociatedControlID=”txtUserName”
Runat=”server” />
<br />
<asp:TextBox id=”txtUserName” Runat=”server” />
<br /><br />
<asp:Label id=”lblConfirmationCode” Text=”Confirmation Code:”
AssociatedControlID=”txtConfirmationCode” Runat=”server” />
<br />
<asp:TextBox id=”txtConfirmationCode”Columns=”50” Runat=”server” />
<asp:Button id=”btnConfirm” Text=”Confirm” OnClick=”btnConfirm_Click” Runat=”server” />
</div>
</form>
</body>
</html>

If the user enters the correct username and confirmation code, then his account is enabled. The MembershipUser.IsApproved property is assigned the value True and the updated user information is saved with the Membership.UpdateUser() method. Using Templates with the CreateUserWizard Control If you need to customize the appearance of the form rendered by the CreateUserWizard control, then you can create templates for the CreateUserWizardStep and the CompleteWizardStep. For example, the page in Listing displays a drop-down list to display options for the security question.

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>CreateUserWizard Template</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:CreateUserWizard id=”CreateUserWizard1” Runat=”server”>
<WizardSteps>
<asp:CreateUserWizardStep>
<ContentTemplate>
<h1>Register</h1>
<asp:Label id=”ErrorMessage” ForeColor=”Red” Runat=”server” />
<br /><br />
<asp:Label
id=”lblUserName” Text=”User Name:” AssociatedControlID=”UserName” Runat=”server” />
<br />
<asp:TextBox id=”UserName” Runat=”server” />
<br /><br />
<asp:Label id=”lblPassword” Text=”Password:” AssociatedControlID=”Password”
Runat=”server” />
<br />
<asp:TextBox id=”Password” TextMode=”Password” Runat=”server” />
<br /><br />
<asp:Label id=”lblEmail” Text=”Email:” AssociatedControlID=”Email” Runat=”server” />
<br />
<asp:TextBox id=”Email” Runat=”server” />
<br /><br />
<asp:Label id=”lblQuestion” Text=”Security Question:” AssociatedControlID=”Question”
Runat=”server” />
<br />
<asp:DropDownList id=”Question” Runat=”server”>
<asp:ListItem Text=”Enter the name of your pet” Value=”Pet Name” />
<asp:ListItem Text=”Enter your favorite color” Value=”Favorite Color” />
</asp:DropDownList>
<br /><br />
<asp:Label id=”lblAnswer” Text=”Security Answer:” AssociatedControlID=”Answer”
Runat=”server” />
<br />
<asp:TextBox id=”Answer” Runat=”server” />
</ContentTemplate>
</asp:CreateUserWizardStep>
<asp:CompleteWizardStep>
<ContentTemplate>
Your account was successfully created.
</ContentTemplate>
</asp:CompleteWizardStep>
</WizardSteps>
</asp:CreateUserWizard>
</div>
</form>
</body>
</html>

In the CreateUserWizardStep, you can add controls with the following IDs:
. UserName
. Password
. Email
. ConfirmPassword
. Question
. Answer
. ErrorMessage

Of course, you can add any other controls that you need. For example, you can request additional information when a new user registers and store the information in a separate database table (see the next section). In the CreateUserWizardStep, you also can add Button controls that contain CommandName properties with the following values:

. CreateUser
. Cancel












No comments:

Post a Comment