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.
<%@ 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
<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