Pages

Advertisement

Friday, July 13, 2007

ASP.NET 2.0 Profile: Simple User Personalization for Your Web Apps

Most enterprise Web applications need to track user preferences across multiple visits. In ASP.NET 1.x, you need to write lots of code to create this functionality. ASP.NET 2.0 introduces a new object, named profile, that simplifies the steps involved in tracking personalization information. This article provides an introduction to the profile object and differentiates it from the session object. It also demonstrates how to define user profiles, both simple name/value pair profiles and profile groups. Finally, it explains the procedures involved in configuring profiles to work with different providers.

An Overview of Profile Object

In an ASP.NET profile, information is stored in a persistent format and is associated with an individual user. The ASP.NET profile allows you to easily manage user information without having to create and maintain your own database. You can store any type of object in the profile because of its generic storage system. In addition, you also can make the same data available in a type-safe manner.

Is the Profile Object the Same as the Session Object?

At first look, the profile object might look very similar to the session object. But, there are a number of differences between the two objects. Table 1 outlines these differences.

Table 1. Differences Between the Profile and Session Objects

Characteristics
Profile
Session

Scope
Each user has his own profile object
Each user has his own session object

Strongly typed nature
Profile object is strongly typed
Session object is not strongly typed and requires type casting when assigning and retrieving from the session object

Persistent duration
Profile values are available for the users, even between visits
Session object contents are available only for the duration of the current browser session

Persistent location
Profile object can be stored in a SQL Server Express database or in a SQL Server database and can be configured through the Web Site Administration tool
Session object can be configured to be stored in a database, IIS in-process, or in a session state server, depending on the configuration setting

Performance
Profile may have a negative impact on performance because of the chatty interface between the profile object and the persistent data store
Can be configured using properties such as EnableSessionState attributes at the page level

IntelliSense
Provides IntelliSense because of its strongly typed nature
No support for IntelliSense

Now that you have a general understanding of the important characteristics of the profile object, take a look at an example.

Defining User Profiles

You define a user profile within the application root web.config file. You cannot create a web.config file containing a profile section in an application subfolder. This means that you can have only one profile element declaration for one Web application. The following declaration in the web.config contains a simple profile definition:

<configuration
xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.web>
<profile>
<properties>
<add name="Name" type="System.String"/>
<add name="UserCount" type="System.Int16"/>
</properties>
</profile>
-----
-----
</system.web>
</configuration>

As you can see, the profile defines two properties: Name and UserCount. The default data type for profile properties is the System.String data type. In the above example, the Name property explicitly declares the data type to be of System.String. The UserCount property is assigned the type Int16 because it is used to represent an integer value.

Once you define a profile, whenever someone requests a page from the Web site ASP.NET automatically generates a class named ProfileCommon that corresponds to the profile definition. This class is stored in the Temporary ASP.NET Files directory, and an instance of this class is made available through the profile property of the HttpContext object.

The following section shows how to utilize this class to access the profile properties.

Working with User Profiles from an ASP.NET Page

Once you have the profiles declared, the next step is to access the profile object from within the ASP.NET page so that you can set or get the values stored in the profile properties. The following code uses the Name and UserCount properties declared in the previous section:

<%@ Page Language="C#" %>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
Profile.UserCount += 1;
}
void btnGetProfileValues_Click(object sender, EventArgs e)
{
lblName.Text = Profile.Name;
lblUserCount.Text = Profile.UserCount.ToString();
}
void btnSetName_Click(object sender, EventArgs e)
{
Profile.Name = txtName.Text;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Accessing Profile object from an ASP.NET Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
Name : <asp:TextBox runat="server" ID="txtName" />
<asp:Button runat="server" ID="btnSetName"
Text="Set Name" OnClick="btnSetName_Click" /><br />
<br/><br/>
<asp:Panel ID="Panel1" runat="server"
Height="224px" Width="265px" BorderColor="LightGray"
BorderStyle="Dotted">
<asp:Button runat="server" ID="btnGetProfileValues"
Text="Get Profile Values"
OnClick="btnGetProfileValues_Click" />
<br/> <br /><br/>
Profile Values: <br />
Name: <asp:Label runat="server" ID="lblName"/>
<br/>
UserCount: <asp:Label runat="server" ID="lblUserCount"/>
</asp:Panel>
</div>
</form>
</body>
</html>

The above listing declares two command buttons. The first, btnSetName, assigns the name entered in the textbox to the Profile.Name property. The click event of the second command button, btnGetProfileValues, results in the values of the profile properties being displayed in the label controls that in turn are contained in a Panel control. In the Page_Load event, the UserCount property is incremented by 1. As you can see from the code listing, setting the value of a profile property is very simple:

Profile.Name = txtName.Text;

Similarly, retrieving the values stored in the profile object is also very simple and straightforward:

lblName.Text = Profile.Name;

Note that you don't need to typecast when retrieving the profile values because the properties stored in the profile object are strongly typed. Navigate to the above page using your browser, set the name, and click on the Get Profile Values button. You should see an output similar to Figure 1.


(
Full Size Image)

Figure 1. Output from "Get Profile Values"

This example enabled Windows authentication through IIS and enabled impersonation through the following settings in the web.config file:

<identity impersonate="true"/>

Note that it enabled impersonation so that the ASP.NET code has sufficient permissions to create a new SQL Server Express database for the first time.

How Profile Properties Are Stored

You might be wondering where exactly the profile properties Name and UserCount are stored in the above example. By default, ASP.NET 2.0 comes with two profile providers: SQL Server Express and SQL Server. By default, the SQL Server Express provider is used. (A later section will show how to change the provider.)

If you refresh your project listing in Solution Explorer, you will notice a database file called ASPNETDB.MDF within the App_Data folder. If you double-click on this database, you will see that the database is opened through the Server Explorer view. Within this database, you will see a table called aspnet_Profile. Figure 2 shows the contents of the table and the values that have been saved through the Profile properties shown in the previous example.


(Full Size Image)

Figure 2. Contents of Table and Values in Profile Properties

Downloads

  • Profile.zip - Download accompanying code - 255 Kb

  •  


    Defining Profile Groups

    Sometimes, you may want to group the related properties into a profile group so that you can easily work with them from your ASP.NET page. For example, the following profile declaration creates a group named UserPreferences that is made up of properties named BackGroundColor, ForeColor, and FontSize:

    <configuration
    xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <system.web>
    <profile>
    <properties>
    <group name="UserPreferences">
    <add name="BackgroundColor" type="System.String"/>
    <add name="ForeColor" type="System.String"/>
    <add name="FontSize" type="System.Int16"/>
    </group>
    </properties>
    </profile>
    -----
    -----
    </system.web>
    </configuration>

    Note: You can have multiple profile group declarations inside the <profile> element. The next section shows how to access the UserPreferences profile group from within an ASP.NET page.

    Working with Profile Groups from an ASP.NET Page

     


    The ASP.NET page shown below has two command buttons that drive the functionality of the page:

    <%@ Page Language="C#" %>
    <script runat="server">
    void btnGetProfileValues_Click(object sender, EventArgs e)
    {
    lblBackground.Text = Profile.UserPreferences.BackgroundColor;
    lblForeColor.Text = Profile.UserPreferences.ForeColor;
    lblFontSize.Text = Profile.UserPreferences.FontSize.ToString();
    Panel1.BackColor = System.Drawing.Color.FromName
    (Profile.UserPreferences.BackgroundColor);
    Panel1.ForeColor = System.Drawing.Color.FromName
    (Profile.UserPreferences.ForeColor);
    Panel1.Font.Size = FontUnit.Parse
    (Profile.UserPreferences.FontSize.ToString());
    }

    void btnSetValues_Click(object sender, EventArgs e)
    {
    Profile.UserPreferences.BackgroundColor = txtBackColor.Text;
    Profile.UserPreferences.ForeColor = txtForeColor.Text;
    Profile.UserPreferences.FontSize =
    Convert.ToInt16(txtFontSize.Text);
    }
    </script>
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
    <title>Accessing Profile Groups from an ASP.NET Page</title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    BackColor: <asp:TextBox runat="server" ID="txtBackColor"/><br/>
    ForeColor: <asp:TextBox runat="server" ID="txtForeColor"/><br/>
    Font Size: <asp:TextBox runat="server" ID="txtFontSize"/><br/>
    <asp:Button runat="server" ID="btnSetName"
    Text="Set Profile Values" OnClick="btnSetValues_Click"/><br/>
    <br/><br/>
    <asp:Panel ID="Panel1" runat="server" Height="224px"
    Width="265px" BorderColor="LightGray" BorderStyle="Dotted">
    <asp:Button runat="server" ID="btnGetProfileValues"
    Text="Get Profile Values" OnClick="btnGetProfileValues_Click" />
    <br/> <br/><br/>
    Profile Values: <br />
    Back Color: <asp:Label runat="server"
    ID="lblBackground"/><br/>
    Fore Color: <asp:Label runat="server"
    ID="lblForeColor"/><br/>
    Font Size: <asp:Label runat="server" ID="lblFontSize"/>
    </asp:Panel>
    </div>
    </form>
    </body>
    </html>

    When the first command button (named btnSetValues) is clicked, the page sets the values of the Profile.UserPreferences group to appropriate values. When the second command button (named btnGetProfileValues) is clicked, it simply retrieves the values of the Profile.UserPreferences group and displays them in label controls. In addition, it sets various properties of the Panel control, such as BackColor, ForeColor, and Size, to the values retrieved from the Profile object.

    Accessing the profile group properties is very similar to accessing the regular profile properties. The only difference is that you need to fully qualify the profile property with the profile group name, as shown below:

        Profile.UserPreferences.BackgroundColor = txtBackColor.Text;
    Profile.UserPreferences.ForeColor = txtForeColor.Text;

    If you request the page from the browser, set the values of the Profile.UserPreferences group using the "Set Profile Values" and then hit the "Get Profile Values" command button. You should see an output somewhat similar to Figure 3.


    (
    Full Size Image)

    Figure 3. Output from "Get Profile Values"

    As you can see from the above output, the Panel control's related properties are assigned from the profile object.

    Using Profiles with Anonymous Users

    The previous examples explained how to utilize the profile feature with users who log in using integrated Windows authentication. Sometimes, you will need to store data in the profile object for anonymous users as well. To accomplish this, you must first enable another ASP.NET 2.0 feature: anonymous identification. You also must mark properties in the <profile> section with a special boolean attribute: allowAnonymous. The following code demonstrates how to set up the web.config file to allow for anonymous users:

    <configuration
    xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <system.web>
    <anonymousIdentification enabled="true"/>
    <profile>
    <properties>
    <add name="Name" allowAnonymous="true"
    type="System.String"/>
    <add name="UserCount"
    allowAnonymous="true"
    type="System.Int16"/>
    </properties>
    </profile>
    -----
    -----
    </system.web>
    </configuration>

    Choosing Profile Providers

    As mentioned before, ASP.NET 2.0 ships with two providers: SQL Server Express and SQL Server. The default provider is SQL Server Express. To change to the SQL Server provider (or your own), use the ASP.NET Web Application Administration tool. Under the Provider tab, click "Select a different provider for each feature (advanced)" and then select the relevant provider in the Profile Provider box.

    In addition to the default providers, you might need to create and use a custom profile provider (for example, you already have a database that stores user information, such as an employee database, or you need to use a database other than SQL Server or in some other format such as XML files). ASP.NET 2.0 also provides the ability to serve the properties stored in a user profile through different profile providers. This provides you the flexibility to manage data from different profile providers from multiple data sources for users of your application using a single user profile.

    Design Personalization-Related Features

    Profile is a very useful feature in ASP.NET 2.0. The object enables you to automatically store user information across multiple visits to a Web application by providing a generic storage system. You can store any type of information within a user profile, including both simple data types such as strings and integers and complex types such as custom objects.

    If you need to design personalization-related features in your Web application, you will find that the new ASP.NET 2.0 Profile object will greatly simplify the design and implementation.

    Downloads

  • Profile.zip - Download accompanying code - 255 Kb
  • 1 comment: