1. Personalizing Web Visits
When the Internet and the Web first began gaining popularity, most sites contained only static
content. That is, they offered only text, graphics, and perhaps links
to other pages. The early Web-surfing community consisted of only the
few folks who knew how to use browsers to peer into the contents of
those early Web servers.
Until the Web began exploding with interactive sites, there was
really no need for Web sites to provide anything but generalized
content. However, savvy businesspeople know that tailoring and targeting
content to specific individuals are good for business.
For example, the next time you go online to shop or visit a
subscription-type site, take note of how much the site knows about you.
Very often, if at some point you provided login information, the site
will greet you by name. It might even point you to information or
products that might interest you. These are examples of how a Web site
can be personalized.
In the early days, any personalization of a site resulted from code you wrote, such as code to manage user preferences in cookies or code to store personal
information in databases. In addition to simply storing and managing
the personal information, you had to integrate the personal
information management with the authentication and authorization scheme
you decided to use. That is, once you authenticated the user, you then could tailor your pages according to his or her personal information.
ASP.NET now includes services for personalizing a Web site to suit a
particular client's taste. There's no reason you can't write your own
database and services to provide this functionality. However, as with
other services, ASP.NET provides a way to do this with consistency and
so that you do not have to write all the code yourself.
2. Personalization in ASP.NET
Although it might not be surprising to find that the ASP.NET personalization services follow the same provider pattern as do authentication and site mapping, defining a Web site's personalization facilities begins by defining user profiles. This section starts there.
The heart of the new ASP.NET personalization service is the user profile.
A user profile defines what kind of personal information your Web site
needs. For example, you might want to know personal data about users of
your Web site, such as name, gender, number of visits to the site, and
so forth. User profiles are also handy for storing user
preferences for your site. For example, you might include a theme as
part of a personal profile so that users can tailor the pages to their
particular tastes.
Once the personalization
properties are defined in web.config, a component in ASP.NET has to be
able to read them and use them. That job is handled by ASP.NET personalization providers.
Personalization Providers
Providers hide the
infrastructural code necessary to support the service, yet they allow
you to choose different underlying storage media with little impact on
your site. Perhaps you start your site using XML files for storing data
but later move to Microsoft SQL Server or you have legacy authentication
databases you want to connect to your ASP.NET site. ASP.NET
personalization is no different. In fact, ASP.NET includes two personalization
providers out of the box: a profile provider for custom user data, and a
personalization provider for Web Parts.
ASP.NET defines the fundamental provider capabilities in an abstract class named PersonalizationProvider.
Those capabilities include loading and saving personalization
properties and managing their relationship to any Web Parts used in a
site. ASP.NET provides a default implementation of these capabilities in
a concrete class named SqlPersonalizationProvider, which is derived from PersonalizationProvider.
Using personalization is straightforward. You define personalization properties in web.config. ASP.NET synthesizes a class for you to use to manage personalization settings. Then, profile information is available in much the same way as session state is available.
Defining Profiles in Web.Config
Your site's profile
schema is defined in web.config as name/type pairs. Imagine that in the
course of designing your site, you decide you would like to track the
following information about a particular user:
-
User name (a string) -
Gender (a Boolean value) -
Visit count (an integer) -
Birthday (a date)
Defining these properties is a matter of specifying them in
web.config. A definition for the properties just mentioned might look
like the following in web.config:
<system.web>
<profile automaticSaveEnabled="true" >
<properties>
<add name="NumVisits" type="System.Int32"/>
<add name="UserName" type="System.String"/>
<add name="Gender" type="System.Boolean">
<add name="Birthday" type="System.DateTime">
</properties>
</profile>
</system.web
Once defined in the web.config file, you can use the profile in the site through the Profile property found in the current HttpContext (and also through the Page base class).
Using Profile Information
To use the profile in your Web site, you access it in much the same
way you might access session state. The Session
member is a name/value dictionary that holds arbitrary information tied
to a particular session. Versions 2, 3, and 3.5 of the ASP.NET compiler
actually synthesize a profile class based on the schema defined in the
web.config file. This is no longer available in ASP.NET 4, where
accessing profile state information is done through the ProfileBase class using name/value pairs.
The ASP.NET class representing the profile information defined in web.config is named ProfileBase. You can access the profile properties using the GetPropertyValue and SetPropertyValue methods like so:
protected void Page_Load(object sender, EventArgs e)
{
ProfileBase profile = HttpContext.Current.Profile;
string name = (string)profile.GetPropertyValue("Name");
if (name != null)
{
Response.Write("Hello " + name);
DateTime dateTime = (DateTime)profile.GetPropertyValue("Birthday");
Response.Write("Your birthday is " +
dateTime);
}
}
The preceding code snippet assumes that there is already personalization
information associated with the user. To insert profile data for a
particular user, simply set the properties of the Profile object. For example, imagine a page that includes a handler for saving the profile. It might look something like this:
protected void ProfileSaveClicked(object sender, EventArgs e)
{ ProfileBase profile = HttpContext.Current.Profile;
profile.SetPropertyValue("Name", this.TextBoxName.Text);
profile.Save();
}
The easiest way to ensure that the personalization properties persist is to set automaticSaveEnabled to true. Personal profile data is then saved automatically by the provider.
Alternatively, you can call Profile.Save as necessary to save the personalization properties manually. In addition to saving and loading profiles, you can also delete the profile for a specific user by calling Profile.DeleteProfile.
Profile information is associated with the current user based on the identity of the user. By default, ASP.NET uses the User.Identity.Name in the current HttpContext as the key to store data. Because of this, profiles are generally available only for authenticated users.
However, ASP.NET supports anonymous profiles as well. As you might expect, this is also configured in web.config. The default tracking mechanism for anonymous profiles is to use cookies. However, you can direct ASP.NET to use a mangled URL. A mangled URL is one in which a key identifying the particular client is embedded in the URL used to post requests back to the server.
The following exercise illustrates using personalization profiles based on the user's login ID.
Using profiles
-
Create a new Web Application project. Name the project MakeItPersonal. -
Microsoft Visual Studio creates a local database including the proper tables to make personalization work. -
Update web.config to include some profile properties, which should be placed in the existing <profile> element. The example here includes a user name, a theme, and a birth date. The following example shows that you can group and nest profile structures in a profile declaration using the group element. Visual Studio adds a <profile> section to the web.config file. Add the configuration information between the <properties> beginning and ending node.
<system.web>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" ... />
</providers>
<properties >
<add name="Theme" type="System.String"/>
<add name="Name" type="System.String"/>
<add name="Birthdate" type="System.DateTime"/>
<group name="Address">
<add name="StreetAddress" type="System.String"/>
<add name="City" type="System.String"/>
<add name="State" type="System.String"/>
<add name="ZipCode" type="System.String"/>
</group>
</properties>
</profile>
</system.web>
Note
This example uses the authenticated user name as the key for locating personalization information. However, ASP.NET supports anonymous personalization.
That is, ASP.NET supports personalization information for anonymous
users—but tracks the users with a cookie. You can add support for anonymous personalization tracking by setting the anonymousIdentification element to true and specifying cookie parameters like this:
<anonymousIdentification enabled="true"
cookieName=".ASPXANONYMOUSUSER"
cookieTimeout="120000"
cookiePath="/"
cookieRequireSSL="false"
cookieSlidingExpiration="true"
cookieProtection="Encryption"
cookieless="UseDeviceProfile" />
In addition to setting up anonymous access in web.config, you need to set the [allowAnonymous] attribute for the properties.
By configuring the site this way and adding the allowAnonymous
attribute to properties in the profile information, ASP.NET will store
the personalization settings based on a cookie it generates when a user
first hits the site.
-
Borrow the Default and SeeingRed themes from the MasterPageSite project .
This allows the user to pick the theme. First, add Default and
SeeingRed folders to the application's Themes directory. Then,
right-click each of the theme folders and click Add Existing Item. -
Borrow the UseThemes.aspx and .cs files from the MasterPageSite
project. If you place them in a separate folder (for example, perhaps a
folder named Secured), you can manage access rights to the folder. -
Update the Default.aspx page. This is where users will enter profile information.
Add text boxes for the name, address, city, state, and zip code.
Add a drop-down list box populated with Default and SeeingRed items to be used for selecting the theme.
Also add a calendar control to pick the birth date. -
Add a button that the user can click to submit profile information.
Add a handler to input these values into the profile. Double-click the
button to add the handler.
The input screen should look something like this:
Note
This example uses the authenticated user name as the key for storing personalization
values. Use the ASP.NET Configuration Utility to apply Forms
Authentication to this application .
Also add at least one user so that you have one to personalize. The
generated project will give you a login page under the Accounts folder.
Add a Login.aspx screen to the site and modify the site's access rules
to enforce authentication so that you can see the personalization information being stored and retrieved.
-
Update Page_Load to display profile information (if it's there). Grab the profile object and set each of the text boxes and the calendar control.
using System.Web.Profile;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
ProfileBase profile = HttpContext.Current.Profile;
string theme = (string)profile.GetPropertyValue("Theme");
this.TextBoxName.Text = (string)profile.GetPropertyValue("Name");
this.TextBoxAddress.Text =
(string)profile.GetPropertyValue("Address.StreetAddress");
this.TextBoxCity.Text = (string)profile.GetPropertyValue("Address.City");
this.TextBoxState.Text =
(string)profile.GetPropertyValue("Address.State");
this.TextBoxZipCode.Text = (string)profile.GetPropertyValue("Address.ZipCode");
this.DropDownList1.SelectedValue =
(string)profile.GetPropertyValue("Theme");
this.Calendar1.SelectedDate = (DateTime)profile.GetPropertyValue("Birthdate");
}
}
} -
Update the profile submission handler to store the profile information:
public partial class _Default : System.Web.UI.Page
{
//...
protected void ButtonSubmitProfile_Click(object sender, EventArgs e)
{
if (this.User.Identity.IsAuthenticated)
{
ProfileBase profile = HttpContext.Current.Profile;
profile.SetPropertyValue("Theme", "SeeingRed");
profile.SetPropertyValue("Name", this.TextBoxName.Text);
profile.SetPropertyValue("Address.StreetAddress", this.TextBoxAddress.Text);
profile.SetPropertyValue("Address.City", this.TextBoxCity.Text);
profile.SetPropertyValue("Address.State", this.TextBoxState.Text);
profile.SetPropertyValue("Address.ZipCode", this.TextBoxZipCode.Text);
profile.SetPropertyValue("Theme", this.DropDownList1.SelectedValue);
profile.SetPropertyValue("Birthdate", this.Calendar1.SelectedDate);
profile.Save();
}
}
} -
Finally, update the UseThemes.aspx page to use the theme. Override the page's OnPreInit method. Have the code apply the theme as specified by the profile:
protected override void OnPreInit(EventArgs e)
{
ProfileBase profile = HttpContext.Current.Profile;
if (profile != null)
{
String strTheme = (string)profile.GetPropertyValue("Theme");
if (strTheme != null &&
strTheme.Length > 0)
{
this.Theme = strTheme;
}
}
base.OnPreInit(e);
}
-
Add a Hyperlink control to the Default.aspx page. Set the Text property to View Themes and set the NavigateURL
property to point to the UseThemes.aspx page. When users surf to the
page, they should be able to enter the profile information and submit
it.
After their initial visit, the profile is available whenever they hit
the site. The following graphic shows the profile information being
displayed in the default page: -
When users visit the UseThemes.aspx page, the page should use the
theme that each user selected in the profile. The following graphic
shows the UseThemes.aspx page using the SeeingRed theme pulled from the profile:
|