An Extended Look at the Profile Object - Part 1
 
Published: 19 Sep 2005
Unedited - Community Contributed
Abstract
There are many reasons to store information about a visitor to your web application. The ASP.NET 1.1 Session object was helpful, but had a number of limitations. Bilal Haidar shows you how the ASP.NET 2.0 Profile object stores user-specific information for both anonymous and authenticated users, and automatically persists this information across separate visits to your website.
by Bilal Haidar
Feedback
Average Rating: 
Views (Total / Last 10 Days): 34868/ 68

Introduction

This is the first article in a series of articles on the new ASP.NET personalization feature, the Profile object. To start with we will explain what the Profile object is and how it differs from the Session object, and then provide simple examples of a Profile object with simple properties and a Profile object with group properties.

To appreciate the value of the Profile object, we need to recognise that there is a common requirement to store user-specific information for the period the user is visiting a web application. In ASP.NET 1.1 we used the Session object. That object has many limitations compared to the new Profile object provided by ASP.NET 2.0. Presently we will compare the Session object and the Profile object. For the moment, we can understand that a Profile object allows the application to store data for each visitor to the web application, save that data to a storage medium like Microsoft SQL Server, and then retrieve the data when the same visitor returns to the application. It has this nice facility of storing profiles not only for authenticated users, but also for anonymous users.

So you might be asking yourself, why would we use the new Profile object when we have the existing Session object? The coming sections of this article will explain how the new Profile object is more flexible and easier to use than the Session object.

What is a User Profile?

A User Profile is the collection of properties that define the information you want to store for users of your web application. A Profile object allows you to automatically save and retrieve user information across multiple visits to a web application. An application's profile object is defined using a simple XML elements in the application's configuration file (web.config). The ASP.NET 2.0 runtime groups these defined properties into a dynamically generated class. When the ASP.NET HTTP lifecycle starts, it dynamically creates a Profile object that contains the properties you have defined in the Profile section of the configuration file, properly typed. The object is then added to the current HttpContext object and is available to pages through the Profile property. Similarly, at the end of the ASP.NET HTTP lifecycle, ASP.NET automatically saves the Profile to the underlying data store. Any type of data can be stored within a user’s profile object, including simple types such as integers and strings, and complex types such as custom business objects.

Despite the fact that the Profile object is most commonly used to store data for authenticated users, the Profile object also supports storing information for anonymous users. This process depends on the Anonymous Identification feature than can be enabled in either the machine.config or web.config file. The Profile object and Anonymous Identification feature work together to enable the use of the Profile property for anonymous users.

How the Profile Object Differs from the Session Object

When developing web applications, we presently use a Session object to store information about the currently logged-in user. For instance, we might store his or her username so that later we can display the user's information in a profile page.

However, there are some limitations with the use of Session objects. Data stored in the session is available only during the current session. After the current session has expired, the next time the user visits the web application, the application must identify the user, load his or her personal information, and again store this information in a new Session object. On the other hand, a Profile object is persistent in the sense that once we store data in a Profile object, it will be automatically persisted to a storage medium, usually a Microsoft SQL Server database, at the end of each page request. The next time the user visits the application, the profile information created or modified during the previous visit will be automatically retrieved. This limitation in the Session object can be eliminated manually by configuring the session state section in the web.config file to store session data in a Microsoft SQL Server database or another data store. With the Profile object, this persistence is automatic. 

A Session object is not strongly typed, as it provides only a collection of items. If you want to access an item stored in the session object, you can do the following:

string item1 = Session["Item1"].ToString();

A profile object has strongly-typed properties. That is, you access its properties in the same way you access properties of any other class. For instance:

string item1 = Profile.Item1;

This way you retrieved the value of Item1 which is a property of the current profile. We can even group properties into logical groups. For instance, a user's profile could contain Street, City, and Country properties. To logically organize your profile object, you would group those three properties into a new profile group named Address. Now, to access each of the properties you can do the following:

string street = Profile.Address.Street;
string city = Profile.Address.City;
string country = Profile.Address.Country;

Another important advantage of the Profile object over the Session object is that each property in the Profile object preserves its own data type, so when using a profile property there is no need to convert it from one data type to another. If we are storing the user’s ID value in a Profile object, so we can directly access its value as an integer without the need to do any conversion. However, in a Session object all items are stored as objects. If we are storing a user’s ID in a Session object, we must convert that session item into integer data type before being able to use it.

When to use a Profile object?

Having said that a Profile object is used to store visitor’s specific information across multiple visits, the question arises, what kind of information can be stored inside a Profile object?

The answer is that any kind of data can be stored, including simple data types like strings and integers, to more complex data types like ArrayLists and custom business objects.

In its simplest form, a website may need to store the username, first name, and last name of the logged in user, and use that information to identify the pages that are accessed by the user. For example, the website might present the user's first and last names at the top of each page.

How to do so with Profile object?

When the user is authenticated by logging in, the application might retrieve from the database the user's first and last names, based on the supplied username and password, and then store the username, first name, and last name in three separate profile properties.

The next time the user visits the web application, there is no need to again retrieve the information from the database and again store it in the Profile object. The ASP.NET 2.0 framework will automatically check the database where the profile data is persisted. If data is found for the identified user, ASP.NET will load the stored data into the current context's Profile object. Now you can use the profile object in the same way you used the first time, without the need to manually repopulate that Profile object. This shows that the data is persisted both within the same session and across many separate sessions.

That was a simple example of the usage of the Profile object. A Profile object can be used in any other scenario where there is a need to persist user-specific information across separate visits to a web application.

Using Simple Profile Properties

In this section, we will start by implementing a user profile that comprises a few simple properties. Listing 1 shows a web.config file with a sample profile configuration section. Note that only one profile configuration section can be defined in a web application. We cannot define another profile section in an application subfolder.

Listing 1: Simple Profile Property Configuration

<configuration>
    <system.web>
        <authentication mode="forms" />
        
        <anonymousIdentification enabled="true" />
        
        <profile enabled="true">
            <properties>
                <add name="FirstName" defaultValue="Bilal" type="string" 
                     allowAnonymous="true" />
                <add name="LastName" defaultValue="Haidar" type="string" 
                     allowAnonymous="true" />
            </properties>
        </profile>
    </system.web>
</configuration>

In this sample web.config file, Forms Authentication and Anonymous Identification are both enabled, thus allowing anonymous Profiles in the web application.

The profile configuration section is enabled and consists of the following custom properties:

  • FirstName: Representing the first name of the user visiting the web application. Its default value is set to Bilal and it is enabled for anonymous users.
  • LastName: Representing the last name of the user visiting the web application. Its default value is Haidar and it too is enabled for anonymous users.

Both profile properties have a data type of string. We could omit that parameter, since the default data type for any profile property is string.

The anonymousIdentification section, when enabled, generates a unique ID for each anonymous visitor. Enabling this feature makes the Profile object available for both anonymous and authenticated users. 

When the Profile section is defined in the web.config file, a Profile class is dynamically generated when the web application starts. This class, which inherits from the ProfileBase class, has strongly typed accessors added for each property defined in the profile section of the configuration file. This class is stored in the Temporary ASP.NET Files directory, which is the same place where the class files are stored for dynamically generated ASP.NET pages. Once the Profile class is generated, an instance is added to the current HttpContext object and populated with either the default values (for a new user) or retrieved values (for a returning user).

Once the Profile configuration section is defined, we can start accessing the Profile object from the server-side code as shown in the code below:

Profile.FirstName = "Johny";

The page in Listing 2 shows how to use a Profile object to persist user-specific information. This page displays a form to modify the values of the user's profile properties, which are FirstName and LastName. Then, after modifying the properties, it will display them above the form (see Figure 1).

Figure 1. Simple Profile Properties

 

Listing 2. SimpleProperties.aspx

<%@ Page Language="C#" %>
<script runat="server">

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            FirstNameTextbox.Text = Profile.FirstName;
            LastNameTextbox.Text = Profile.LastName;
        }
    }
    protected void Modify_Click(object sender, EventArgs e)
    {
        if (!string.IsNullOrEmpty(FirstNameTextbox.Text))
            Profile.FirstName = FirstNameTextbox.Text;
        if (!string.IsNullOrEmpty(LastNameTextbox.Text))
            Profile.LastName = LastNameTextbox.Text;
    }
    protected void Page_PreRender(object sender, EventArgs e)
    {
        FirstNameLabel.Text = Profile.FirstName;
        LastNameLabel.Text = Profile.LastName;
    }

</script>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Simple Profile Properties</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>
            Simple Profile Properties</h1>
        <h3>
            Current Properties</h3>
        <p>
            First Name : <asp:Label ID="FirstNameLabel" runat="server" /><br />
            Last Name : <asp:Label ID="LastNameLabel" runat="server" /><br />
            </p>
        <hr />
        <h3>
            Modify Properties</h3>
        <p>
            First Name : <asp:TextBox ID="FirstNameTextbox" runat="server" /><br />
            Last Name : <asp:TextBox ID="LastNameTextbox" runat="server" /><br />
            </p>
        <p>
            <asp:Button ID="Modify" OnClick="Modify_Click" Text="Modify Profile"
                runat="server" />
            </p>
    </div>
    </form>
</body>
</html>

The SimpleProperties page in Listing 2 shows the Profile object in action. Notice that in Listing 1 we have enabled anonymousIdentification. We have also set allowAnonymous to true for both Profile properties. This allows us to access those properties even when the visitor to the web page is an anonymous user, which is the case when testing the page above.

Notice that if the browser is closed and then the same page opened again, the last modified values are displayed. This shows that the Profile properties were persisted, even for an anonymous user.

Finally, if we set allowAnonymous to false for each property, and try to set a profile property while the current visitor is an anonymous user, an exception would be thrown saying that one cannot access a Profile property that is not configured to be used by anonymous users.

Using Group Profile Properties

In the previous section we demonstrated how to define simple properties in the profile section of the web.config file. Sometimes when developing a web application, we may need to group a set of properties within the Profile object. For instance, one might be developing a web application for a school, where the application needs to store a student’s details in a Profile object, in addition to storing other Profile properties. The way to do so is to place the student’s details in a group section in the profile configuration section. In Listing 3 below, we have a profile configuration section that includes a group section named Student, which defines the student details of FirstName, LastName, and StudentId.

Listing 3. Group Profile Property Configuration

<configuration>
    <system.web>
        <authentication mode="forms" />

        <anonymousIdentification enabled="true" />

        <profile enabled="true">
            <properties>
                <group name="Student">
                    <add name="FirstName" allowAnonymous="true" />
                    <add name="LastName" allowAnonymous="true" />
                    <add name="StudentId" allowAnonymous="true" type="Int32" />
                </group>
            </properties>
        </profile>
    </system.web>
</configuration>

Listing 3 defines a group section named Student and specifies its three properties. The first two, FirstName and LastName, do not have a defined type, which means that they are of the default type of string. The third property, which is StudentId, has a type of Int32 representing the student's ID number.

Once the group profile configuration section is defined, we can start accessing the Profile object’s Student property from the server-side code, as shown in the code below:

Profile.Student.StudentId = 9898;
Profile.Student.FirstName = "Johny";
Profile.Student.LastName = "White";

The page in Listing 4 shows how to use a Profile group object to persist a student’s details. This page displays a form to view and modify the values of the Profile's Student group property (see Figure 2).

Figure 2. Group Profile Properties

 

Listing 4. GroupProperties.aspx (C#)

<%@ Page Language="C#" %>
<script runat="server">

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            StudentIDTextbox.Text = Profile.Student.StudentId.ToString();
            FirstNameTextbox.Text = Profile.Student.FirstName;
            LastNameTextbox.Text = Profile.Student.LastName;
        }
    }
    protected void Modify_Click(object sender, EventArgs e)
    {
        if (!string.IsNullOrEmpty(StudentIDTextbox.Text))
        {
            int IntId;
            Profile.Student.StudentId = 
                (int.TryParse(StudentIDTextbox.Text, out IntId)) ? IntId : 0;
        }
        if (!string.IsNullOrEmpty(FirstNameTextbox.Text))
            Profile.Student.FirstName = FirstNameTextbox.Text;
        if (!string.IsNullOrEmpty(LastNameTextbox.Text))
            Profile.Student.LastName = LastNameTextbox.Text;
    }
    protected void Page_PreRender(object sender, EventArgs e)
    {
        StudentIDLabel.Text = Profile.Student.StudentId.ToString();
        FirstNameLabel.Text = Profile.Student.FirstName;
        LastNameLabel.Text = Profile.Student.LastName;
    }

</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Group Profile Properties</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>
            Group Profile Properties</h1>
        <h3>
            Current Properties</h3>
        <p>
            Student ID : <asp:Label ID="StudentIDLabel" runat="server" /><br />
            First Name : <asp:Label ID="FirstNameLabel" runat="server" /><br />
            Last Name : <asp:Label ID="LastNameLabel" runat="server" /><br />
            </p>
        <hr />
        <h3>
            Modify Properties</h3>
        <p>
            Student ID : <asp:TextBox ID="StudentIDTextbox" runat="server" /><br />
            First Name : <asp:TextBox ID="FirstNameTextbox" runat="server" /><br />
            Last Name : <asp:TextBox ID="LastNameTextbox" runat="server" /><br />
            </p>
        <p>
            <asp:Button ID="Modify" OnClick="Modify_Click" Text="Modify Student Profile"
                runat="server" />
            </p>
    </div>
    </form>
</body>
</html>

Once the Modify Student Profile button is clicked, the Profile's Student group properties are updated with the new values entered.

One thing to mention is that we cannot nest one group section within another group section. However, we can have as many group sections as we want in the Profile configuration section.

Conclusion

In this first part of our series on the ASP.NET personalization feature, we defined what the Profile object is, when to use it, and how it is different from the Session object. In addition, we examined how to define both simple properties and group properties by updating the profile configuration section of the web.config file.

In the coming series, we will discuss more advanced topics of the Profile object, such as defining custom objects in the profile configuration section, and how to retrieve, delete, update, search, and otherwise manage profiles. We will also discuss how to configure the Profile object to work with Microsoft SQL Server 2000 instead of Microsoft SQL Server 2005, how to move an anonymous profile to an authenticated profile, and many more interesting features.

Happy Dot Netting!



User Comments

Title: HELP   
Name: Ahamd
Date: 2010-03-29 8:22:16 AM
Comment:
Hi, I used this tutorial, but i get an error msg as, "Unable to connect to SQL Server database." I do not hav a SQL instance in my system. I'll hav to connect to a server in a network PC. So plz tell me what modifications i'll hav to do to run the code.
Title: Thank you   
Name: blad3runn69
Date: 2009-01-14 10:30:07 PM
Comment:
Thank you for the info and code Bilal, very helpful and muchly appreciated. :)
Title: An Extended Look at the Profile Object - Part 1   
Name: swapnil
Date: 2008-08-18 10:00:09 AM
Comment:
good one.
Title: Same Topic, Different Framework   
Name: RichardW
Date: 2008-04-25 5:39:37 PM
Comment:
Thank you. I always seem to get stuck on context. This got me past the context issues of Profiles in ASP.NET Membership.

Wondering if anyone in house has thought to go in depth on this same topic of Membership/Profiles but from the context of Ajax and Silverlight as the framework using ASP.NET 3.5 in the background. At the Olympics this year, NBC will be streaming with Silverlight... It's gonna be a boost for the technology, would like to come up to speed with others on it using the foundations of ASP.NET 3.5/Ajax to control it.
Title: Still don't see the point   
Name: Craig
Date: 2008-03-27 9:42:08 PM
Comment:
Good article but I really don't see the point of the profile object. If you're going to register users on a web site you'll have built that in to your DB schema and be authenticating them against that. Therefore, no point in having some bot do it for you.

If you're an anonymous user, how on earth can a system know who you are when you return to pick out your profile data again? I bet it's only available if you return within the session timeout period. In which case, use sessions, it's MUCH easier. It's becoming like you need a degree in computer science just to write a simple web page with .NET.
Title: Profiles with Web Applications   
Name: Mark
Date: 2007-06-11 9:44:59 AM
Comment:
Did you ever notice that if you use a web application instead of a website, the profile object is not available? Instead, you can access the currently logged on user profile through context.current.profile. The problem is, if you want to change information during the registration process, you can't do it. Do you have any way to change info in the profile of a user who isn't logged on using a web application?
Title: Thanks   
Name: john
Date: 2007-06-11 8:23:03 AM
Comment:
This helped me a lot to understand profile object.
Title: Fantastic Inroduction Article   
Name: |__Roshan__|
Date: 2007-02-09 4:04:06 AM
Comment:
This a fantastic intoduction article of the new ASP.NET personalization feature, the Profile object..
Title: Good Stuff!   
Name: Adi
Date: 2006-07-02 2:37:24 AM
Comment:
Nice intro! Easy and enjoyable to follow especially for .net newbie like me :)
Thanks Bilal!
Title: Re: All   
Name: Bilal Haidar [MVP]
Date: 2006-03-16 5:23:08 AM
Comment:
I am very glad you are happy with this article.

Thank you all.
Title: Good   
Name: Lajpathrai.Y
Date: 2006-03-16 4:43:37 AM
Comment:
Thanks a lot to author. really a good explanation. will useful to freshers
Title: Great Intro   
Name: Ed
Date: 2006-01-18 8:38:59 PM
Comment:
Perfect extension of the MS explanation (which was lacking a bit).
Title: Comment   
Name: Mihir Solanki
Date: 2005-12-24 9:17:06 PM
Comment:
Thanks, Perfect introduction
Title: Comment   
Name: Rainer
Date: 2005-11-17 10:31:58 AM
Comment:
Fine. But I am looking now for an easy way to work with these additional user profile properties. Like: Show me all users with zip code x.
Title: Nice article   
Name: Matthew Lee
Date: 2005-11-08 4:19:40 AM
Comment:
Nice, Informative stuff...






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2021 ASPAlliance.com  |  Page Processed at 2021-04-16 10:37:16 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search