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.

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.

Figure 2. Contents of Table and Values in Profile Properties

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

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.

[Profile3.JPG]

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.

About the Author

Thiru Thangarathinam has six years of experience in architecting, designing, developing, and implementing applications using object-oriented application development methodologies. He also possesses a thorough understanding of the software life cycle (design, development, and testing). He holds several certifications, including MCAD for .NET, MCSD, and MCP. Thiru is an expert with ASP.NET, .NET Framework, Visual C# .NET, Visual Basic .NET, ADO.NET, XML Web services, and .NET Remoting. Thiru also has authored numerous books and articles. Contact him at thiruthangarathinam@yahoo.com.



Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • It's hardly surprising that half of small businesses fail within the first 1-5 years. It's not easy to launch a new product, single-handedly manage everything from IT to accounting, fend off the competition, and grow a customer base – all at the same time – even with a great concept. Offering awesome customer service can make the difference between a startup that flies and a startup that dies. Read this white paper to learn nine ways customer support can help you beat the competition and grow your …

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds