Wednesday, April 16, 2008

Sending an Activation Email with ASP.NET 2.0 Expanded

I had a request to show an example that would build on my original "Sending an Activation Email with ASP.NET 2.0" to provide a user with a link to log them in. What follows shows how you can place a link on the final Account Details page that when clicked will take the user to a Login page with their username already pre-filled for them.

Activate.aspx

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Activate.aspx.cs" Inherits="Activate" %>
<!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 runat="server">
<title>Activation Page</title>
</head>
<body>
<form id="form1" runat="server">
<br />
<asp:Table ID="Table1" runat="server" CellPadding="1" CellSpacing="0" GridLines="Both" BorderStyle="Groove" BackColor="BlanchedAlmond" Caption="Account Information">
<asp:TableRow>
<asp:TableCell HorizontalAlign="Right" runat="server">Username:</asp:TableCell>
<asp:TableCell HorizontalAlign="Left" runat="server"><asp:Label ID="ActiviationNameLabel" runat="server" Style="position: static"></asp:Label></asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell HorizontalAlign="Right" runat="server">Account Created:</asp:TableCell>
<asp:TableCell HorizontalAlign="Left" runat="server"><asp:Label ID="ActivationCreationDateLabel" runat="server" Style="position: static"></asp:Label></asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell HorizontalAlign="Right" runat="server">Account Status:</asp:TableCell>
<asp:TableCell HorizontalAlign="Left" runat="server"><asp:Label ID="ActivationStatusLabel" runat="server" style="position: static"></asp:Label></asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell HorizontalAlign="Right" runat="server">
<br />
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Login.aspx">Goto Login Page</asp:HyperLink>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</form>
</body>
</html>
Activate.aspx.cs

This updated code stores the username in a Session variable, so that it can be used to populate the Username field of the Login Control.

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string userID = Request.QueryString["ID"];
Guid gd = new Guid(userID);
MembershipUser user = Membership.GetUser(gd);
user.IsApproved = true;
Roles.AddUserToRole(user.ToString(), "Power Users");
Membership.UpdateUser(user);
ActiviationNameLabel.Text = user.UserName;
ActivationCreationDateLabel.Text = user.CreationDate.ToShortDateString();
if (user.IsApproved)
{
ActivationStatusLabel.Text = "Active";
}
else
{
ActivationStatusLabel.Text = "Pending";
}

Session["UserName"] = user.UserName;
}
}
Login.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<!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 runat="server">
<title>Login Page</title>
</head>
<body>
<form id="form1" runat="server">
<div style="text-align: center">
<asp:Login ID="Login1" runat="server" BackColor="#F7F6F3" BorderColor="#E6E2D8" BorderPadding="4" BorderStyle="Solid" BorderWidth="1px" Font-Names="Verdana" Font-Size="0.8em" ForeColor="#333333" DestinationPageUrl="~/Main.aspx">
<TextBoxStyle Font-Size="0.8em" />
<LoginButtonStyle BackColor="#FFFBFF" BorderColor="#CCCCCC" BorderStyle="Solid" BorderWidth="1px"
Font-Names="Verdana" Font-Size="0.8em" ForeColor="#284775" />
<InstructionTextStyle Font-Italic="True" ForeColor="Black" />
<TitleTextStyle BackColor="#5D7B9D" Font-Bold="True" Font-Size="0.9em" ForeColor="White" />
</asp:Login>
</div>
</form>
</body>
</html>
Login.aspx.cs

This simple Login page retrieves the user's Username from the session and assigns it to the Login controls UserName TextBox. It first checks to see if the session variable is null or empty if it is then the Login Control's UserName TextBox is left blank.

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (!(String.IsNullOrEmpty((string)Session["UserName"])))
{
string username = Session["UserName"].ToString();
Login1.UserName = username;
}
else
{
Login1.UserName = string.Empty;
}
}
}
Main.aspx
Upon successful login the user is redirected to a simple welcome page called Main.aspx.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Main.aspx.cs" Inherits="Main" %>
<!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 runat="server">
<title>Main Website Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:LoginView ID="LoginView1" runat="server">
<LoggedInTemplate>
Welcome
<asp:LoginName ID="LoginName1" runat="server" />
!<br />
<br />
<asp:LoginStatus ID="LoginStatus1" runat="server" LogoutAction="RedirectToLoginPage"
LogoutPageUrl="~/Login.aspx" />
</LoggedInTemplate>
</asp:LoginView>
&nbsp;</div>
</form>
</body>
</html>




8 comments:

bindu said...

Hi,
Thanks for posting this article. But when I tried to run this code I am getting an error on this line.
Roles.AddUsersToRole(user.ToString(), "Power Users");

cannot convert from 'string' to 'string[]

Please help me.

Bindu.

Lance Spence said...

Have you already created the "Power Users" Role in your ASPNETDB database?

bindu said...

No I didnt create "Power Users" in my ASPNETDB database.Can you please explain me how to do that?
I am very new to ASP.NET.
Thanks,
Bindu.

Lance Spence said...

Open the website in VS2005 or Visual Web Developer.

- Click Website on the top menu.
- Select ASP.NET Configuration.
- Click on the Security Tab.
- Under Roles, select Create or Manage roles.
- Enter "Power Users" for the role name and click Add Role.

bindu said...

I already tried that..but when I click the security tab I am getting some error.

There is a problem with your selected data store. This can be caused by an invalid server name or credentials, or by insufficient permission. It can also be caused by the role manager feature not being enabled. Click the button below to be redirected to a page where you can choose a new data store.

The following message may help in diagnosing the problem: "Unable to connect to SQL Server database".

I am using SQL server express edition and login the computer using administrator.
Thanks,
Bindu.

Lance Spence said...

You have something else going on which could be one of a number of things.

I would Google that error and see if you can find the appropriate solution.

One quick thing, when you ran ASPNET_REGSQL did you choose the defaults or add specific providers (eg: Roles, Profiles, etc.)?

bindu said...

When I ran ASPNET_regexe ,I choose

1.Configure SQL Server for application services
2.Windows Authentication or SQL Authentication.....>I choose windows Authentication and choose one of the existing database(not default)
3.In Setting summary....>It showed Server name and Database Name.
4.The Database has been created or modified.

I didnt see any option...> for choose the defaults or add specific providers (eg: Roles, Profiles, etc.)..which u were mensioning.

Lance Spence said...

I would suggest running ASPNET_REGSQL again and when prompted for the Database, choose the default. This will create a database called ASPNETDB with all the of the providers added.

I mentioned I wasn't sure how you ran the ASPNET_REGSQL command, because it can be invoked with a gui or by passing it command-line options. Invoking it by passing command-line options gives you more control over which providers to create or remove.

You might want to visit the following link for more information on ASPNET_REGSQL and it's various command-line options.

http://msdn2.microsoft.com/en-us/library/x28wfk74(VS.80).aspx