Section 13.3. Anonymous Personalization

13.3. Anonymous Personalization

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 only need to log in when you are ready to purchase what is in your cart).

ASP.NET 2.0 supports the ability to link anonymous personalized data with a specific user's personalized data, once that user logs in (you don't want to lose what's in your cart when you do log in).

Begin by creating a new web site named AnonymousPersonalization. Delete Default.aspx and copy the SitePersonalization web site to your new site, and test that it is working as expected.

Next, to enable anonymous personalization , you must update your web.config file, adding the following in the <system.web> section:

  <anonymousIdentification enabled="true" />  

Also, add the attribute-value pair allowAnonymous="true" to the CHOSENBOOKS element of web.config .

Redesign your Welcome.aspx page so the hyperlink that links to the profile information page, and the lbBooks list box, are both 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, since you will be using this link to add, and edit, the profile info , as shown in Example 13-3.

Example 13-3. Modified Welcome.aspx
 <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Welcome.aspx.cs"    Inherits="Welcome_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>Welcome</title> </head> <body>     <form id="form1" runat="server">     <div>         <asp:LoginStatus ID="LoginStatus1" runat="server" />         <asp:LoginView ID="LoginView1" runat="server">             <LoggedInTemplate>                 Welcome                 <asp:LoginName ID="LoginName1" runat="server" />                 <br />                 <asp:HyperLink                     ID="hlChangePW"                     NavigateUrl="ChangePW.aspx"                     runat="server">Change Password                  </asp:HyperLink>                  &nbsp;                  <asp:HyperLink                     ID="hlCreateUser"                     NavigateUrl="CreateUser.aspx"                     runat="server">Create User                  </asp:HyperLink>                 <br />                 <asp:HyperLink                     ID="hlManageRoles"                     NavigateUrl="ManageRoles.aspx"                     runat="server">Manage Roles                 </asp:HyperLink> <br />             </LoggedInTemplate>             <AnonymousTemplate>                 You are not logged in.                 Please click the login link to log in to this system.             </AnonymousTemplate>  </asp:LoginView>         <asp:HyperLink             ID="hlProfile"             NavigateUrl="ProfileInfo.aspx"             runat="server">Profile Information         </asp:HyperLink>         <asp:ListBox  ID="lbBooks" runat="server" />  <asp:Panel ID="pnlInfo" Runat="server" Visible="False"            Width="422px" Height="63px">             <br />             <table width="100%">                 <tr>                 <td style="height: 21px">                     <asp:Label ID="lblFullName" Runat="server"                     Text="Full name unknown">                     </asp:Label></td>                 </tr>                 <tr>                 <td>                     <asp:Label ID="lblPhone" Runat="server"                     Text="Phone number unknown">                     </asp:Label>                 </td>                 </tr>                 <tr>                 <td>                     <asp:Label ID="lblBirthDate" Runat="server"                         Text="Birthdate  unknown">                     </asp:Label>                 </td>                 </tr>             </table>       </asp:Panel>     </div>  </form> </body> </html> 

When an anonymous user chooses books, that user will automatically be assigned a Globally Unique Identifier (GUID) , and an entry will be made in the database. However, only those properties marked with allowAnonymous will 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:

 protected void Page_Load(object sender, EventArgs e)     {        if ( !IsPostBack )        {           if (Profile.IsAnonymous == true)           {              this.pnlNonAnonymousInfo.Visible = false;           }           else           {              this.lastName.Text = Profile.lastName;              this.firstName.Text = Profile.firstName;              this.phone.Text = Profile.phoneNumber;              this.birthDate.Text = Profile.birthDate.ToShortDateString(  );           }                     // end if not anonymous           if (Profile.CHOSENBOOKS != null)           {              foreach (ListItem li in this.cblChosenBooks.Items)              {                 foreach (string profileString in Profile.CHOSENBOOKS)                 {                    if (li.Text == profileString)                    {                       li.Selected = true;                    }         // end if text matches                 }            // end for each profile string              }               // end for each item in list           }                  // end if chosen books not null        }                     // end if not postback /user name not null     }                        // end page load 

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

Modify the ProfileInfo page so the non-anonymous data is in a panel that will be invisible for users who are not logged in, as shown in Example 13-4.

Example 13-4. Modified ProfileInfo.aspx
 <%@ Page Language="VB" AutoEventWireup="false" CodeFile="ProfileInfo.aspx.cs"    Inherits="ProfileInfo_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>Profile Information</title> </head> <body>     <form id="form1" runat="server">     <div>  <asp:Panel ID="pnlNonAnonymousInfo" runat="server">             <table>             <tr>                 <td>First Name: </td>                 <td style="width: 193px">                   <asp:TextBox ID="txtFirstName" Runat="server" />                 </td>             </tr>             <tr>                 <td>Last Name: </td>                 <td style="width: 193px">                  <asp:TextBox ID="txtLastName" Runat="server" /></td>             </tr>             <tr>                 <td>Phone number: </td>                 <td style="width: 193px">                    <asp:TextBox ID="txtPhone" Runat="server" />                 </td>             </tr>             <tr>                 <td>BirthDate</td>                 <td style="width: 193px">                    <asp:TextBox ID="txtBirthDate" Runat="server" />                 </td>             </tr>         </table>         </asp:Panel>  <table>              <tr>                 <td>                     <asp:CheckBoxList ID="cblChosenBooks" runat="server">                         <asp:ListItem>Programming C#</asp:ListItem>                         <asp:ListItem>Programming ASP.NET</asp:ListItem>                         <asp:ListItem>Programming .NET Apps</asp:ListItem>                         <asp:ListItem>Agile Software Development</asp:ListItem>                         <asp:ListItem>UML2 For Dummies</asp:ListItem>                         <asp:ListItem>                            Object Oriented Design Heuristics                         </asp:ListItem>                         <asp:ListItem>Design Patterns</asp:ListItem>                     </asp:CheckBoxList>                 </td>              </tr>              <tr>                 <td>                    <asp:Button ID="save" Text="Save" Runat="server"                        OnClick="save_Click" />                  </td>                 <td style="width: 193px"></td>             </tr>         </table>     </div>     </form> </body> </html> 

Remove the test for whether IsAnonymous is false in Profile.info.aspx.cs save_Click so the assignment to the profile happens whether or not the user is anonymous:

 protected void save_Click(object sender, EventArgs e)     {        if (Profile.IsAnonymous == false)        {           Profile.lastName = this.lastName.Text;           Profile.firstName = this.firstName.Text;           Profile.phoneNumber = this.phone.Text;           DateTime birthDate = Convert.ToDateTime(this.birthDate.Text);           Profile.birthDate = birthDate;        }  Profile.CHOSENBOOKS = new System.Collections.Specialized.StringCollection(  );  foreach (ListItem li in this.cblChosenBooks.Items)        {           if (li.Selected)           {              Profile.CHOSENBOOKS.Add(li.Value.ToString(  ));           }        }        Response.Redirect("Welcome.aspx");     } 

Fix Page_Load in Welcome.aspx.cs as well to display the anonymous list of books:

 protected void Page_Load(object sender, EventArgs e)     {        if ( ! Profile.IsAnonymous )        {           this.pnlInfo.Visible = true;           this.lblFullName.Text = Profile.firstName + " " + Profile.lastName;           this.lblPhone.Text = Profile.phoneNumber;           this.lblBirthDate.Text = Profile.birthDate.ToShortDateString(  );           this.lbBooks.Items.Clear(  );        }        else        {           this.pnlInfo.Visible = false;        }  if (Profile.CHOSENBOOKS != null)        {           foreach (string bookName in Profile.CHOSENBOOKS)           {              this.lbBooks.Items.Add(bookName);           }        }  } 

Run the application. Do not log in; click the Profile Info link. Select a few books and click Save. When you return to the Welcome page, you will still not be logged in, but your selected books are displayed, as shown in Figure 13-9.

Figure 13-9. Anonymous user information

Stop the application and reopen the database. Open the apsnet_Users table and the aspnet_Profile tables. You'll see that an ID has been created for the anonymous user (and the UserName has been set to the GUID generated). In addition, the chosen books list has been stored in the corresponding record, as shown in Figure 13-10.

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, for example, shopping cart items are not lost). You do this by writing a handler for the global MigrateAnonymous event that is fired when a user logs in. This handler must be named Profile_MigrateAnonymous (case sensitive) and is created within the script tags in global.asax :

Figure 13-10. Anonymous user record in database

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

If your project does not have a global.asax file, right-click on the project and choose Add New Item. One of your choices will be Global Application Class, and it will default to the name global.asax . Click Add.


The first step in the event handler is to get a reference to the profile that matches the AnonymousID passed in as a property of the ProfileMigrateEventArgs structure (shown in bold).

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

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

Figure 13-11. Profiles merged



Programming ASP. NET
Programming ASP.NET 3.5
ISBN: 0596529562
EAN: 2147483647
Year: 2003
Pages: 173

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