Profile Provider

Views: This article has been read 141129 times.
Abstract: This tutorial covers the majority of features the ASP.NET Profile Provider can offer, including, a basic introduction to the provider and what it can be used for; migrating an anonymous profile to authenticated profile; inheriting from the ProfileBase class; grouping profile properties; managing user profiles; and personalizing a Website using the provider in conjunction with the ASP.NET WebPartManager and WebPartZone WebControls.

Profile Provider

In general, the Profile provider is used to save and retrieve user data (including anonymous user data) to and from the aspnet_Profile table (part of the existing aspnetdb database). This information tracks the logged on user or anonymous user and can save several defined pieces of data while modifying this data as the user navigates through the Website. This feature could track many things in a Web application.

Using the Profile provider is an alternative to using session objects. It is a solution for tracking the user from one page to the next—without any risk to increasing the server’s memory. It also increases user sessions dramatically because it’s not based on the Web server’s user session time. A user can remain logged in to a Website for several hours, even days, without doing anything in it and the application will keep the user logged in. It also has many more built-in properties and methods through the Profile object than the Session object and provides a much more efficient way of storing persistent data. It also can migrate anonymous user data (user not logged in) to an authenticated user (after user logs in), like Amazon.com’s Website.

The Profile object derives from the System.Web.Profile.ProfileBase class. When a Web application that has the user profile enabled is started, ASP.NET creates a new instance of the profile object, which inherits from the ProfileBase class. User data is handled through this instantiated ProfileCommon object and customized properties defined in the web.config file. For example, customized properties could be defined as “CustomerNumber” and “DateModified”, which would store the customer number and date of the last form a user modified, as shown in the following code. Second, passing the actual data to these properties would be done by entering Profile.CustomerNumber= tbCustNum.Text when the form is saved. These actions are handled through the ProfileCommon GetPropertyValue and SetPropertyValue methods. Beyond this, pretty much everything else is handled by the Profile provider, including, saving the values to the proper tables. Information can go far beyond this simple application, including remembering user settings, specific data displayed from the database, etc. By default, user profile is disabled and requires to be enabled in the web.config file, as shown below.

<system.web>

<roleManager enabled="true" />
 <authentication mode="Forms"/>
 <anonymousIdentification enabled="true" />

 <profile enabled="true">
  <properties>
   <add name="CustomerNumber" allowAnonymous="true"/>
   <add name="DateModified" type="System.DateTime" />
  </properties>
 </profile>

</system.web>

Behind the scenes, the Profile provider would save the customer number and date modified to the aspnet_Profile table in the PropertyNames column and the values in the PropertyValuesString column. The Profile provider efficiently saves this data through a colon-delimited list of items, saving as one string in the PropertyNames column, the properties names and types, and the values’ starting and ending positions (e.g. CustomerNumber:S:0:8:DateModified:S:9:16:), and saving the values as one string in the PropertyValuesString column. The following code demonstrates how data could be saved and viewed to and from the Profile collection from any Web page.

If Profile.Anonymous = False Then   ‘store data in user’s profile
 Profile.CustomerNumber= tbCustNum.Text
 Profile.DateModified = tbDateModified.Text
End If

If Profile.CustomerNumber IsNot Nothing Then   ‘view anonymous user’s data
 lblLastCustNum.Text = Profile.CustomerNumber
End If

The specific Profile provider for SQL Server databases is AspNetSqlProfileProvider, which derives from the System.Web.Security.SqlMembershipProvider namespace. This provider saves and retrives the data from aspnetdb. This provider is registered in the machine.config file that is used with the Web application, as shown in the following code. Multiple providers can be used and specific data defined in web.config can be used with specific providers using the provider="MyProvider" attribute.

<profile enabled="true">
<providers>
          <add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="/" type="System.Web.Profile.SqlProfileProvider, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</profile>

The Profile provider uses many methods and stored procedures. The following is a list of some of the methods and all 6 of the Profile’s stored procedures: SetPropertyValues(), GetPropertyValues(), aspnet_Profile_GetProfiles, aspnet_Profile_GetProperties, aspnet_Profile_SetProperties, aspnet_Profile_DeleteInactiveProfiles, aspnet_Profile_DeleteProfiles, aspnet_Profile_GetNumberOfInactiveProfiles.

Migrating Anonymous Profile to Authenticated Profile

This information can also be saved for an anonymous user before the user logs on. As an anonymous user, the Profile provider assigns and saves a UserName (e.g. “1db6964f-577d-426f-80c4-a57f3a1ff5e7”) and UserId (e.g. “67FBECF5-8A38-4674-84FA-E4C8D4575A3F”) to the aspnet_Users table, assigns the value “1” to the IsAnonymous column, and saves the user data to the aspnet_Profile table. When the user logs on, the Profile provider migrates the anonymous profile (data) to the user’s authenticated profile. This occurs through an an event called Profile_MigrateAnonymous, as shown in the following code, which would need to be added to a global.asax file. When the anonymous user logs in, the event fires. The anonymous ID that was assigned to the anonymous user is then passed to the ProfileMigrateEventArgs structure, a parameter of the event. This is then used to get a reference to the user’s authenticated profile that matches the anonymous profile based on the anonymous ID.

Sub Profile_MigrateAnonymous(ByVal sender As Object, ByVal e As ProfileMigrateEventArgs)
    Dim anonymousProfile As ProfileCommon = Profile.GetProfile(e.AnonymousID)
    If ((Not (anonymousProfile) Is Nothing) AndAlso (Not (anonymousProfile.UserPrefs.Links) Is Nothing)) Then
        For Each s As String In anonymousProfile.UserPrefs.Links
            Profile.UserPrefs.Links.Remove(s)
            Profile.UserPrefs.Links.Add(s)
        Next
    End If
End Sub

A setting for anonymous users to track them is required in the web.config file, as shown in the following example. It automatically generates a unique ID for anonymous users. By default cookies stored regardless of whether the browser or device supports cookies.

<anonymousIdentification enabled="true" cookieName="AnonymousUser" />

You can clear the cookie that was previously created for the anonymous user, when the anonymous user logs in, as shown in the following example. This code snippet is placed in the global.asax in the Profile_MigrateAnonymous subroutine. It removes the cookie and prevents the MigrateAnonymous event from constantly firing on each page after the user has logged in.

AnonymousIdentificationModule.ClearAnonymousIdentifier()

Inheriting from ProfileBase Class

There are two ways of modularizing complex profiles. Modularizing profiles using these techniques provides greater manageability to the data and provides built-in intellisense in Visual Studio.NET.

One technique is to inherit from the ASP.NET ProfileBase class. The following example shows how a class named “UserInfo” derives from System.Web.Profile.ProfileBase to provide custom user properties to be used throughout the application. This class could then be placed in the Web application’s App_Code directory. By doing this, the class would automatically be compiled at runtime, to provide easy maintenance and future development to the class. Further, when a new property is added and the class saved, instantly, the property appears in VS.NET intellisense.

Public Class UserInfo
    Inherits ProfileBase

    Private _FirstName As String
    Private _LastName As String
    Private _BirthDate As Date
    Private _Address As String
    Private _City As String
    Private _State As String
    Private _Zip As String

    Public Property FirstName() As String
        Get
            Return _FirstName
        End Get
        Set(ByVal value As String)
            _FirstName = value
        End Set
    End Property  
 .
 .
 .
End Class

To use the “UserInfo” class throughout the application, a simple setting is made in the web.config file, as shown below. This directs the profile provider to inherit from the custom “UserInfo” class. When creating profile properties in a custom class, VS.NET intellisense will organize these properties according. For example, the properties created in “UserInfo” would cause a “Profile.FirstName” intellisense.

<profile inherits="UserInfo" >

Grouping Profile Properties

Another technique to create better manageability to the custom profile properties is to group them in the web.config file, as shown below. When grouping properties, VS.NET intellisense will organize these properties according. For example, the following setting in the web.config file would cause a “Profile.UserPrefs.ChosenBooks” intellisense. This data model is eventually transformed into Visual Basic.NET and becomes part of a class, created by the ASP.NET runtime. ProfileBase.Create returns an instance of a dynamically created class that derives from ProfileBase and is used with the ProfileCommon object.

<properties>

 <group name="UserPrefs">
  <add name="ChosenBooks" type="System.Collections.Specialized.StringCollection"
   allowAnonymous="true" />
  <add name="PageVisits" type="Int32" allowAnonymous="true"/>
  <add name="ReceiveNewsletter" type="System.Boolean" defaultValue="false"
  allowAnonymous="true" />
  <add name="FavoriteColor" allowAnonymous="true" defaultValue="Red" />
  <add name="SurveyCompleted" type="Boolean" allowAnonymous="true" />
  <add name="FavoriteLanguage" allowAnonymous="true" />
  <add name="FavoriteEnvironment" allowAnonymous="true" />
 </group>

</properties>

Managing User Profiles

The ASP.NET ProfileManager class can be used to manage user profiles. The namespace is System.Web.Profile.ProfileManager. This class has a number of utility methods that can be used to manage profiles and generate reports on profiles. The following example will display all user profiles on page load, including their username, size of their profile files, whether or not their anonymous, last date their profile was updated and their last activitiy.

Protected Sub Page_Load1(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ResultsGrid.DataSource = ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All)
        ResultsGrid.DataBind()
End Sub

Another useful function of the ProfileManager class is the DeleteInactiveProfiles. With this function, profiles of users inactive after a specified period of time could be removed from the database to free up space, as shown in the following example.

ProfileManager.DeleteInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now.AddDays(-7))
Console.WriteLine("Deleted " & deleted & " profiles" )

By Todd Paholsky