7.1. Personalize Your Application
Note: Use the Profile object to remember your users' preferences.
Chapter 5 introduces the new ASP.NET Membership Provider and shows you how to use it to manage users easily. Using the new Membership Provider makes managing user logins straightforward. However, the membership feature does not store information about the users it lists, such as their preferences for themes, their shipping addresses, or lists of previous purchases.
To remember a user's preferences, you can use the new Profile service (exposed via the Profile object) in ASP.NET 2.0. Think of the Profile service as a mechanism to persistently store a user's information, similar to the Session object. Unlike a Profile object, however, a Session object is valid only for the duration of a session; after the session has expired, the Session object is deleted. The Profile service, however, retains its information until you explicitly remove it from the data store.
Moreover, the Profile object has several advantages over the Session object, such as:
Profile object data is persisted in data stores, whereas Session variables are saved in memory.
- Strong typing
Profile object properties are strongly typed, unlike Session variables, which are stored as Objects and typecast during runtime.
- Efficient implementation
Profile properties are loaded only when they're needed, unlike Session variables, which are all loaded whenever any one of them is accessed.
In ASP.NET 2.0, the new Profile object allows user's data to be persisted in a much more efficient manner.
7.1.1. How do I do that?
If you want to use the Profile object to store personalized information about your users, you need a way to identify users so their usernames can act as keys to the information stored in the data store. In this lab, you will build an application that prompts the user to save her name when she first visits your site. Subsequently, when she visits the page again, you will be able to retrieve her name from the Profile object.
Launch Visual Studio 2005 and create a new web site project. Name the project C:\ASPNET20\chap07-Profile.
Drag and drop a Panel control onto the default Web Form and add a 2 3 table (Layout Insert Table) into the Panel control. Populate the form with the controls shown in Figure 7-1.
Figure 7-2. Populating the default page with all the controls
The default Web Form will prompt the user to enter her name when she first visits the page. The next time the user visits the page, the application will be able to remember her name. You will use the Profile object to save the user's name. To use the Profile object, you first need to add a web configuration file to your project. Right-click on the project name in Solution Explorer, select Add New Item..., and select Web Configuration File from the Template pane of the Add New Item dialog.
Add the <profile> element to the Web.config file as follows:
<system.web> <profile> <properties> <add name="FirstName" type="System.String"/> <add name="LastName" type="System.String"/> </properties> </profile> ...
You have defined two Profile properties, FirstName and LastName, which will be used to store a user's first and last name, respectively. You have also specified the data types to be used for the properties. You can use any type that is available in the framework (so long as they are serializable). To use either of the two Profile properties, simply prefix the property name with the keyword Profile. That is, Profile.FirstName and Profile.LastName.
Attributes in the Profile Property
Besides the name and the type attribute (any .NET data type; the default is string), you can also specify the following attributes:
Indicates whether the property is read-only.
Represents how the property value should be stored in the database. Possible values are String (default), Xml, Binary, and ProviderSpecific.
The name of the profile provider to use.
The default value of the property.
Whether the property can store values by anonymous users.
Double-click the default Web Form to switch to its code-behind page. In the Page_Load event, first check to see if the FirstName property is nonempty. If it is nonempty, you will retrieve the first and last name of the user from the Profile properties. If it is empty, you can assume this is the first time the user is visiting the page, and you can show the Panel control to allow the user to enter her first and last name.
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles Me.Load If Profile.FirstName <> "" Then Panel1.Visible = False Response.Write("Welcome back, " & _ Profile.FirstName & ", " & _ Profile.LastName) Else Panel1.Visible = True End If End Sub
When the user clicks the Save button, you save the first and last names by simply assigning them to the Profile properties. Code the Save button as:
Protected Sub btnSave_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles btnSave.Click ' save the profile Profile.FirstName = txtFirstName.Text Profile.LastName = txtLastName.Text Response.Write("Thank you, " & _ txtFirstName.Text & ", " & txtLastName.Text) End Sub
To test the application, press F5. Figure 7-2 shows what happens when the user loads the Web Form for the first time. The user can then enter her name and click Save to save her name in the Profile object. When the user comes back to visit the page again, she will be greeted with a welcome message, instead of having to reenter her name (see Figure 7-3).
Figure 7-3. Loading the page for the first time
Figure 7-4. Subsequent visit by the user
7.1.2. What just happened?
When you run the application, the user's first and last names are saved in the Profile properties. So where are these values stored?
ASP.NET 2.0 uses a Profile Provider to store the data saved in the Profile object. By default, the SQL Server 2005 Express Provider is used.
To examine the values stored by the Profile object, double-click the ASPNETDB.MDF file located under the App_Data folder in your project.
You should now see the ASPNETDB.MDF database under the Data Connections item in Server Explorer (see Figure 7-4). Expand the Tables node to view the list of tables within this database.
Figure 7-5. Examining the aspnetdb database
Right-click on the aspnet_Profile table and select Show Table Data. You should now be able to see the values stored in the table (see Figure 7-5).
Figure 7-6. Examining the aspnet_Profile table
Note the UserID field of the aspnet_Profile table. It is used to uniquely identify the Profile object associated with a particular user for this application. If you further examine the aspnet_Users table (see Figure 7-6), the UserID field has a corresponding ApplicationID field (that identifies the application) and a UserName field (that identifies the user).
Figure 7-7. Examining the aspnet_Users table
Notice that the UserName is "WINXP2\Wei-Meng Lee." For this application, you are using the default Windows authentication for your ASP.NET application. Therefore, you should see your own Windows login name.
7.1.3. What about...
...grouping related Profile properties?
Suppose you want to save the address of a user. Instead of using the following structure:
Profile.Line1 = "" Profile.Line2 = "" Profile.State = "" Profile.Zip = ""
it would be more logical to organize all related information into a group, like this:
Profile.Address.Line1 = "" Profile.Address.Line2 = "" Profile.Address.State = "" Profile.Address.Zip = ""
To do so, simply use the <group> element in Web.config:
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <system.web> <profile> <properties> <add name="FirstName" type="System.String" /> <add name="LastName" type="System.String" /> <add name="LastLoginTime" type="System.DateTime" /> <group name="Address"> <add name="Line1" type="System.String" /> <add name="Line2" type="System.String" /> <add name="State" type="System.String" /> <add name="Zip" type="System.String" /> </group> </properties> </profile> </system.web> </configuration>
7.1.4. Where can I learn more?
You can write your own Profile Provider if you do not want to use the one provided by Microsoft. For example, you may wish to persist the Profile properties in an XML file instead of a SQL Server database. For more information on the ASP.NET 2.0 Provider Model, check out these two articles by Rob Howard: