A Deeper Look at Personalization using Visual Basic 2005

In this third part of a four-part series covering personalization with Visual Basic 2005, we'll learn about anonymous personalization, themes and skins, and more. This article is excerpted from chapter 12 of the book Programming Visual Basic 2005, written by Jesse Liberty (O'Reilly, 2005; ISBN: 0596009496).

Contributed by
Rating: 3 stars3 stars3 stars3 stars3 stars / 5
November 30, 2006
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Personalize with Complex Types

To make a useful commercial site, you often have to store complex user-defined types (classes) or collections.

In the next exercise, you’ll edit the Web.config file to add a collection of strings called CHOSENBOOKS. Doing so will allow the user to choose one or more books, and have those choices stored in the user’s profile.

Add a line to Web.config for your new property:

  <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" />
    </properties>
  </profile>
 

To see this collection at work, edit the page ProfileInfo.aspx, inserting a row with a CheckBoxList just above the row with the Save button, as shown in Figure 12-37.


Figure 12-37.  Adding checkboxes to profile

Modify the Save button handler to add the selected books to the profile, as shown in Example 12-14.

Example 12-14. Code to modify Save button Click event handler

Profile.CHOSENBOOKS = New System.Collections.Specialized.StringCollection()
For Each item As ListItem In Me.cblChosenBooks.Items
    If item.Selected Then
        Profile.CHOSENBOOKS.Add(item.Value.ToString())
    End If
Next

Each time you save the books, you create an instance of theString collection, and you then iterate through the checked list boxes, looking for the selected items. Each selected item is added to the string collection within the profile (theCHOSENBOOKSproperty).

You also need to overridePage_Loadso that this page will open with the user’s profile information updated, as shown in Example 12-15.

Example 12-15. Modified ProfileInfo.aspx.vb

Partial Class ProfileInfo
   
Inherits System.Web.UI.Page
   Protected Sub save_Click( _
   ByVal sender As Object, _
   ByVal e As System.EventArgs) Handles save.Click
     
If Profile.IsAnonymous = False Then
         Profile.lastName = Me.lastName.Text
         Profile.firstName = Me.firstName.Text
         Profile.phoneNumber = Me.phone.Text
         Profile.birthDate = CType(Me.birthDate.Text, System.DateTime)

        Profile.CHOSENBOOKS
=
           New System.Collections. Specialized.StringCollection()
        For Each item As ListItem In Me.cblChosenBooks.Items
           If item.Selected Then
              Profile.CHOSENBOOKS.Add(item.Value.ToString())
           End If
        Next 
     
End If
     
Response.Redirect("Welcome.aspx")
  End Sub
  Protected Sub Page_Load(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Me.Load
    
If Not IsPostBack And Profile.UserName IsNot Nothing Then 
       
If Profile.IsAnonymous = False The
n
          Me.lastName.Text = Profile.lastName
          Me.firstName.Text = Profile.firstName
          Me.phone.Text = Profile.phoneNumber
          Me.birthDate.Text = Profile.birthDate.ToShortDateString()
       End If
         If Profile.CHOSENBOOKS IsNot Nothing Then
            For Each theListItem As ListItem In Me.cblChosenBooks.Items
            For Each theProfileString As String In Profile.CHOSENBOOKS
               If theListItem.Text = theProfileString Then
                 theListItem.Selected = True
               End If
            Next
         Next
       End If
     End If
  End Sub
End Class

Each time you navigate to the Profile page, the values are updated from the existing profile (if any) in Page_Load and you are free to change them and save the new values, as shown in Figure 12-38.


Figure 12-38.  Profile Information page with CheckBoxList

To confirm that this data has been stored, add aListBox(name itlbBooks) to the pnlInfo panel you added to Welcome.aspx page, as shown in Figure 12-39.


Figure 12-39.  ListBox added to panel

Bind the ListBox to the collection in the profile, as shown in Example 12-16.

Example 12-16. Modified Page_Load in Welcome.aspx.vb

Protected Sub Page_Load(_
ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
  
If Not IsPostBack And Profile.UserName IsNot Nothing Then
      Me.pnlInfo.Visible = True
      If Profile.IsAnonymous = False Then
         Me.lblFullName.Text = Profile.firstName & " " & Profile.lastName
         Me.lblPhone.Text = Profile.phoneNumber
         Me.lblBirthDate.Text = Profile.birthDate.ToShortDateString()
     
End If
     
If Profile.CHOSENBOOKS IsNot Nothing Then
        For Each bookName As String In Profile.CHOSENBOOKS
           Me.lbBooks.Items.Add(bookName)
        Next
     End If
  Else
     Me.pnlInfo.Visible = False
  End If
End Sub

When you click Save in the Profile page and return to the Welcome page, your saved profile information is reflected, as shown in Figure 12-40.


Figure 12-40.  Welcome page with chosen books

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 personalization for anonymous users as well as the ability later to link anonymous personalized data with a specific user’s. Once that user logs in, you don’t want to lose what was in the user’s cart.

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

  <anonymousIdentification enabled="true" />

Add the attribute-value pair allowAnonymous="true" to the CHOSENBOOKS element of Web.config, as shown in Example 12-17.

Example 12-17. Modified Web.config for anonymous access

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/
.NetConfiguration/v2.0">
   <connectionStrings>
    
<remove name="LocalSqlServer"/>
    
<add name="LocalSqlServer" connectionString="data source=.\SqlExpress;Integrated Security=SSPI;Initial Catalog=aspnetdb"/>
   </connectionStrings>
   <system.web>
      <anonymousIdentification enabled="true" /> 
      <roleManager enabled="true" />
     
<authentication mode="Forms"/>
     
<membership defaultProvider="AspNetSqlMembershipProvider"/>
     
<compilation debug="true"/>
     
<profile enabled="True" defaultProvider="AspNetSqlProfileProvider">
        
<properties>
           
<add name="lastName" />
           
<add name="firstName" />
           
<add name="phoneNumber" />
           
<add name="birthDate" type="System.DateTime"/>
           
<add name="CHOSENBOOKS" allowAnonymous="true" 
             type="System.Collections. Specialized.StringCollection" />
        
</properties>
     
</profile>
    </system.web>
</configuration>

Redesign your Welcome.aspx page in two ways: first move the hyperlink to the profile Information page outside of the Logged In template. Second move the listbox (lbBooks) outside the panel. Thus, you can see both of these features whether or not you are logged in. Also, change the text on the Add Profile Info hyperlink to just Profile Info, since you will be using this link to add and edit the profile info.

When an anonymous user fills in the profile information, 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 withallowAnonymous may be stored, so you must modify yourSave_Clickevent handler in ProfileInfo.aspx.vb. Bracket the entries for all the profile elements except CHOSENBOOKSin anIfstatement that tests whether the user is currentlyAnonymous. The newsave_Clickevent handler for ProfileInfo.aspx.vb is shown in Example 12-18.

Example 12-18. Modified Save_Click event handler for ProfileInfo.aspx.vb

Protected Sub save_Click(_
ByVal sender As Object, _
ByVal e As System.EventArgs) Handles save.Click
   
If Profile.IsAnonymous = False Then
      Profile.lastName = Me.lastName.Text
      Profile.firstName = Me.firstName.Text
      Profile.phoneNumber = Me.phone.Text
      Profile.birthDate = CType(Me.birthDate.Text, System.DateTime)
   End If
   Profile.CHOSENBOOKS = New System.Collections.Specialized. StringCollection()
   For Each item As ListItem In Me.cblChosenBooks.Items
     
If item.Selected Then
         Profile.CHOSENBOOKS.Add(item.Value.ToString())
     
End If
   Next
   Response.Redirect("Welcome.aspx")
End Sub

The effect of the new code shown in Example 12-18 is that you check whether theIsAnonymousproperty is false. If it is, then you are dealing with a logged-in user, and you can get all of the properties; otherwise, you can get only those that are allowed for anonymous users.

Modify the ProfileInfo page so that the non-anonymous data is in a panel that will be invisible for users who are not logged in. The simplest way to do this may be to switch to Source view and bracket the nonanonymous code inside a panel (don’t forget to end the table before ending the panel), as shown in Example 12-19.

Example 12-19. Adding a nonanonymous information panel to ProfileInfo.aspx.vb

<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="FirstName" Runat="server" />
               
</td>
            </tr>
            <tr>
               
<td>Last Name: </td>
                <td style="width: 193px">
                 <asp:TextBox ID="LastName" Runat="server" /></td>
            </tr>
            <tr>
               
<td>Phone number: </td>
                <td style="width: 193px">
                   <asp:TextBox ID="Phone" Runat="server" />
                </td>
            </tr>
           
<tr>
                <td>BirthDate</td>
                <td style="width: 193px">
                   <asp:TextBox ID="BirthDate" Runat="server" />
                </td>
            </tr>
        </table>
       </asp:Panel>

Modify the Page_Load for ProfileInfo.aspx to hide the panel if the user is anonymous, as shown in Example 12-20.

Example 12-20. Modified page load—ProfileInfo.aspx.vb

Protected Sub Page_Load(ByVal sender As Object, _
 ByVal e As System.EventArgs) Handles Me.Load
  If Not IsPostBack And Profile.UserName IsNot Nothing Then
     If Profile.IsAnonymous = True Then
        Me.pnlNonAnonymousInfo.Visible = False
    
Else
        Me.pnlNonAnonymousInfo.Visible = True
        If Profile.IsAnonymous = False Then
           Me.lastName.Text = Profile.lastName
           Me.firstName.Text = Profile.firstName
           Me.phone.Text = Profile.phoneNumber
           Me.birthDate.Text = Profile.birthDate.ToShortDateString()
       
End If

        If Profile.CHOSENBOOKS IsNot Nothing Then
           For Each theListItem As ListItem In Me.cblChosenBooks.Items
              For Each theProfileString As String In Profile.CHOSENBOOKS
                 If theListItem.Text = theProfileString Then
                    theListItem.Selected = True
                 End If
              Next
           Next
        End If   'Profile.CHOSENBOOKS IsNot Nothing
     End If      'Profile.IsAnonymous = True
  End If         'Not IsPostBack And Profile.UserName IsNot Nothing
End Sub

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 Welcome page, you are still not logged in, but your selected books are displayed, as shown in Figure 12-41.

Stop the application and reopen the database. You’ll see that an ID has been created for this anonymous user (and theUserNamehas been set to the GUID generated). In addition, the profile information has been stored in the corresponding record, as shown in Figure 12-42.


Figure 12-41.  Anonymous user information


Figure 12-42.  Anonymous user record in database

Migrating the Anonymous Data to the Actual User’s Record

When the user does log in, you must migrate the Profile data you’ve accumulated for the anonymous user to the 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 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). Within that class, add a method to handle theMigrateAnonymousevent that is fired when a user logs in, as shown in Example 12-21.

Example 12-21. MigrateAnonymous event handler

Sub Profile_MigrateAnonymous( _
ByVal sender As Object, ByVal e As ProfileMigrateEventArgs)
    Dim anonymousProfile As ProfileCommon = _
       Profile.GetProfile(e.AnonymousId)
    If anonymousProfile IsNot Nothing And _
        anonymousProfile.CHOSENBOOKS IsNot Nothing Then
        For Each s As String In anonymousProfile.CHOSENBOOKS
            Profile.CHOSENBOOKS.Remove(s)  ' remove duplicates
            Profile.CHOSENBOOKS.Add(s) 
        Next
    End If
End Sub

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

  Dim anonymousProfile As ProfileCommon = _
     
Profile.GetProfile(e.AnonymousId)

If the reference is notNothing, then you know that there is a matching anonymous profile, and that you may choose whatever data you need from that profile. In this case, you copy over theCHOSENBOOKScollection.

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 12-43.


Figure 12-43.  Profiles merged

Themes and Skins

Many users like to personalize their favorite web sites by setting the look and feel to meet their own aesthetic preferences. ASP.NET 2.0 supports that requirement with “themes.”

A theme is a collection of skins. A skin describes how a control should look. A skin can define style sheet attributes, images, colors, and so forth.

Having multiple themes allows your users to choose how they want your site to look by switching from one set of skins to another at the touch of a button. Combined with personalization, your site can remember the look and feel each user prefers.

There are two types of themes. The first, called stylesheet themes, define styles that may be overridden by the page or control. These are, essentially, equivalent to CSS style sheets. The second type, called customization themes, cannot be overridden. You set a stylesheet theme by adding the StyleSheetTheme attribute to the page directive, and, similarly, you set a customization theme by setting the Theme attribute in the page directive.

In any given page, the properties for the controls are set in this order:

  • Properties are applied first from a stylesheet theme.
  • Properties are then overridden based on properties set in the control.
  • Properties are then overridden based on a customization theme.

Thus, the customization theme is guaranteed to have the final word in determining the look and feel of the control.

Skins themselves come in two flavors: default skins and explicitly named skins. Thus, you might create a Labels skin file with this declaration:

  <asp:Label runat="server"
  ForeColor="Blue" Font-Size="Large"
  Font-Bold="True" Font-Italic="True" />

This is a default skin for all Label controls. It looks like the definition of anASP:Labelcontrol, but it is housed in a skin file and, thus, is used to define the look and feel of all Label objects within that skin file’s theme.

In addition, however, you might decide that some labels must be red. To accomplish this, create a second skin, but assign this skin aSkinIDproperty:

  <asp:Label runat="server" SkinID="RedLabel"
 
ForeColor="Red" Font-Size="Large"
  Font-Bold="True" Font-Italic="True" />

Any label that does not have aSkinIDattribute will get the default skin; any label that setsSkinID ="Red"will get your named skin.

The steps to providing a personalized web site are:

  1. Create the test site.
  2. Organize your themes and skins.
  3. Enable themes and skins for your site.
  4. Specify themes declaratively if you wish.

Please check back next week for the conclusion of this article.

blog comments powered by Disqus
VISUAL BASIC.NET ARTICLES

- Basic Form Properties and Modality in VB.NET
- Multiple Document Interfaces in Visual Basic
- Visual Basic for Beginners
- ASP.NET Image to PDF with VB.Net
- MySQL in ASP.NET: Mono using VB.NET
- AsyncFileUpload File Type and File Size Vali...
- Visual Studio: Adding Functionality and Style
- Clocks and Countdowns
- User-defined Functions using Visual Basic Ap...
- Understanding Object Binding in VBA
- Mastering the Message Box
- Testing a Windows Forms Application
- Using Visual Basic.NET Features to Code a Wi...
- Correcting Code in a Windows Forms Applicati...
- Write Readable Code and Comments for Windows...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 6 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials