Section 4.6. Add Anonymous Personalization to Your Site


4.6. Add Anonymous Personalization to Your Site

It is common to allow your users to personalize your site before identifying themselves. A classic example of this is Amazon.com, which lets you add books to your shopping cart before you log in (you need to log in only to actually purchase what is in your cart).

ASP.NET 2.0 supports personalization and, even more important, the ability to link the anonymous data with a user's personalized data once that user logs in (you don't want the user to lose what is in his cart when he does log in).


Note: It is common practice to allow users to personalize your site before identifying themselves.

4.6.1. How do I do that?

Once again, use Copy Web Site to copy the previous lab to a new web site called AnonymousPersonalization.

To enable anonymous personalization you must update your Web.config file:

<?xml version="1.0"?> <configuration>    <system.web>       <anonymousIdentification enabled="true" />   <authentication mode="Forms"/>       <roleManager enabled="true"/>       <compilation debug="true"/>         <profile>             <properties>                 <add name="lastName" />                 <add name="firstName" />                 <add name="phoneNumber" />                 <add name="birthDate" type="System.DateTime" />                 <add name="CHOSENBOOKS"                   type="System.Collections.Specialized.StringCollection"                  allowAnonymous="true" />              </properties>         </profile>                  </system.web> </configuration>

Add the attribute-value pair allowAnonymous="true" to the CHOSENBOOKS element of Web.config.

Redesign your Default.aspx page so that both the hyperlink that links to the Profile Information page and the lbBooks listbox are outside of the LoginView control (so you can see the hyperlink and the list, even if you are not logged in). While you are at it, rename Add Profile Info to Profile Info because you will be using this link to add and edit the profile information, as shown in Example 4-4.

Example 4-4. Modified Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"  Inherits="Default_aspx" %>      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/ DTD/xhtml11.dtd">      <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">     <title>Untitled Page</title> </head> <body>     <form  runat="server">     <div>         <asp:LoginStatus  Runat="server" />         <asp:LoginView  Runat="server" >                         <LoggedInTemplate>                 Welcome                  <asp:LoginName  Runat="server" />                            </LoggedInTemplate>             <AnonymousTemplate>                 You are not yet logged in             </AnonymousTemplate>         </asp:LoginView>         <asp:HyperLink  Runat="server" NavigateUrl="~/AddUser.aspx"> Add User</asp:HyperLink>         <asp:HyperLink  Runat="server" NavigateUrl="~/ ManageRoles.aspx">Manage Roles</asp:HyperLink>         <asp:Panel  Runat="server" Visible="False" Width="422px"  Height="63px">             <br />             <table width="100%">                 <tr><td><asp:Label  Runat="server"   Text="Full name unknown"></asp:Label></td></tr>                 <tr><td><asp:Label  Runat="server"  Text="Phone number unknown"></asp:Label></td></tr>                 <tr><td><asp:Label  Runat="server"   Text="Birthdate  unknown"></asp:Label></td></tr>             </table>          </asp:Panel>                  <asp:HyperLink  Runat="server"                 NavigateUrl="~/ProfileInfo.aspx">Profile Info</ asp:HyperLink>                 <br />  <asp:ListBox   Runat="server" />                     </div>     </form> </body> </html>

When an anonymous user chooses books, the user will automatically be assigned a Globally Unique Identifier (GUID), and an entry will be made in the database for that ID. However, note that only those properties marked with allowAnonymous can be stored, so you must modify your save_Click event handler in ProfileInfo.aspx.cs. Bracket the entries for all the profile elements except CHOSENBOOKS in an if statement that tests whether the user is currently Anonymous, as shown in the following snippet:

if (Profile.IsAnonymous =  = false) {    Profile.lastName = this.lastName.Text;    Profile.firstName = this.firstName.Text;    Profile.phoneNumber = this.phone.Text;    Profile.birthDate = Convert.ToDateTime(this.birthDate.Text); } Profile.CHOSENBOOKS =     new System.Collections.Specialized.StringCollection( );

When saving your profile data, you check whether the IsAnonymous property is false. If it is false, you know you are dealing with a logged-in user, and you can get all the properties; otherwise, you can get only those that are allowed for anonymous users.

Before you run the application, however, you must enable the anonymous identification feature. To do so, add the following attribute-value pair to the top of your Web.config file:

<anonymousIdentification enabled="true" />

Run the application. Do not log in, but do click the Profile Info link. Select a few books and click Save. When you return to the default page, you are still not logged in, but your selected books are displayed, as shown in Figure 4-36.

Figure 4-36. Book list for anonymous user


Stop the application and reopen the database. You'll see that an ID has been created for this anonymous user and UserName has been set to the GUID generated. In addition, the shopping cart has been stored in the corresponding record, as shown in Figure 4-37.

Figure 4-37. Anonymous User record in database


4.6.2. What about...

...migrating the anonymous data to the actual user's data?

When the user does log in, you must migrate the profile data you've accumulated for the anonymous user to the appropriate authenticated user's record (so that, for example, shopping cart items are not lost). You do this by writing a global handler in global.asax.

If your project does not yet have a global.asax file, right-click the project and choose Add New Item. One of your choices will be Global Application Class, and it will automatically be named global.asax. Within that class, add a method to handle the MigrateAnonymous event that is fired when a user logs in, as shown in the following snippet:

void Profile_MigrateAnonymous(object sender, ProfileMigrateEventArgs e) {   ASP.HttpProfile anonymousProfile = Profile.GetProfile(e.AnonymousId);   if (anonymousProfile != null && anonymousProfile.CHOSENBOOKS != null)   {     foreach (string s in anonymousProfile.CHOSENBOOKS)     {       Profile.CHOSENBOOKS.Remove(s);  // avoid duplicates       Profile.CHOSENBOOKS.Add(s);     }   } }

The first step in this method is to get a reference to the profile that matches the AnonymousID that is passed in as a property of the ProfileMigrateEventArgs structure:

ASP.HttpProfile anonymousProfile = Profile.GetProfile(e.AnonymousId);

If the reference is not null, you know there is a matching anonymous profile, and you can pick up whatever data you need from that profile. In this case, copy over the CHOSENBOOKS collection.


Note: To associate anonymous data with a user who has decided to log in, you must write a global handler in global.asax.

The user's profile is updated, and the books chosen by the anonymous user are now part of that user's profile, as shown in Figure 4-38.

Figure 4-38. Profiles merged


4.6.3. Where can I learn more?

For more information, see my article "Personalization in ASP.NET 2.0" on ONDotnet (http://www.ondotnet.com), as well as the article "Personalization with ASP.NET 2.0" by Patel et. al, in the MSDN Library.



Visual C# 2005(c) A Developer's Notebook
Visual C# 2005: A Developers Notebook
ISBN: 059600799X
EAN: 2147483647
Year: 2006
Pages: 95
Authors: Jesse Liberty

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net