To store an item, you simply populate the personalization property directly using theProfileobject: Profile.FirstName = TextBox1.Text To retrieve the same information, you simply grab th
Trang 1<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Storing Personalization</title>
</head>
<body>
<form id="form1" runat="server">
<p>First Name:
<asp:TextBox ID="TextBox1" Runat="server"></asp:TextBox></p>
<p>Last Name:
<asp:TextBox ID="TextBox2" Runat="server"></asp:TextBox></p>
<p>Age:
<asp:TextBox ID="TextBox3" Runat="server" Width="50px"
MaxLength="3"></asp:TextBox></p>
<p>Are you a member?
<asp:RadioButtonList ID="Radiobuttonlist1" Runat="server">
<asp:ListItem Value="1">Yes</asp:ListItem>
<asp:ListItem Value="0" Selected="True">No</asp:ListItem>
</asp:RadioButtonList></p>
<p><asp:Button ID="Button1" Runat="server" Text="Submit"
OnClick="Button1_Click" />
</p>
<hr /><p>
<asp:Label ID="Label1" Runat="server"></asp:Label></p>
</form>
</body>
</html>
C#
<%@ Page Language="C#" %>
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
if (Page.User.Identity.IsAuthenticated)
{
Profile.FirstName = TextBox1.Text;
Profile.LastName = TextBox2.Text;
Profile.Age = TextBox3.Text;
Profile.Member = Radiobuttonlist1.SelectedItem.Text;
Profile.LastVisited = DateTime.Now.ToString();
Label1.Text = "Stored information includes:<p>" +
"First name: " + Profile.FirstName +
"<br>Last name: " + Profile.LastName +
"<br>Age: " + Profile.Age +
"<br>Member: " + Profile.Member +
"<br>Last visited: " + Profile.LastVisited;
}
else
{
Label1.Text = "You must be authenticated!";
}
}
</script>
Trang 2This is similar to the way you worked with theSessionobject in the past, but note that the
personaliza-tion properties you are storing and retrieving are not key based Therefore, when working with them you
do not need to remember key names
All items stored by the personalization system are type cast to a particular NET data type By default,
these items are stored as typeString, and you have early-bound access to the items stored To store an
item, you simply populate the personalization property directly using theProfileobject:
Profile.FirstName = TextBox1.Text
To retrieve the same information, you simply grab the appropriate property of theProfileclass as
shown here:
Label1.Text = Profile.FirstName
The great thing about using theProfileclass and all the personalization properties defined in the code
view is that this method provides IntelliSense as you build your pages When you are working with the
Profileclass in this view, all the items you define are listed as available options through the IntelliSense
feature, as illustrated in Figure 15-2
Figure 15-2
Trang 3All these properties are accessible in IntelliSense because theProfileclass is hidden and dynamically
compiled behind the scenes whenever you save the personalization changes made to theweb.configfile After these items are saved in theweb.configfile, these properties are available to you throughout your application in a strongly typed manner
When run, the page from Listing 15-2 produces the results shown in Figure 15-3
Figure 15-3
In addition to using early-bound access techniques, you can also use late-bound access for the items that you store in the personalization engine This technique is illustrated in Listing 15-3
Listing 15-3: Using late-bound access
VB
Dim myFirstName As String
myFirstName = Profile.GetPropertyValue("FirstName").ToString()
Continued
Trang 4string myFirstName;
myFirstName = Profile.GetPropertyValue("FirstName").ToString();
Whether it is early-bound access or late-bound access, you can easily store and retrieve personalization
properties for a particular user using this capability afforded by ASP.NET 3.5 All this is done in the
personalization engine’s simplest form — now take a look at how you can customize for specific needs
in your applications
Adding a Group of Personalization Properties
If you want to store a large number of personalization properties about a particular user, remember that
you are not just storing personalization properties for a particular page, but for the entire application.
This means that items you have stored about a particular end user somewhere in the beginning of the
application can be retrieved later for use on any other page within the application Because different
sections of your Web applications store different personalization properties, you sometimes end up with
a large collection of items to be stored and then made accessible
To make it easier not only to store the items, but also to retrieve them, the personalization engine enables
you to store your personalization properties in groups This is illustrated in Listing 15-4
Listing 15-4: Creating personalization groups in the web.config file
<configuration>
<system.web>
<profile>
<properties>
<add name="FirstName" />
<add name="LastName" />
<add name="LastVisited" />
<add name="Age" />
<group name="MemberDetails">
<add name="Member" />
<add name="DateJoined" />
<add name="PaidDuesStatus" />
<add name="Location" />
</group>
<group name="FamilyDetails">
<add name="MarriedStatus" />
<add name="DateMarried" />
<add name="NumberChildren" />
<add name="Location" />
</group>
</properties>
Trang 5<authentication mode="Windows" />
</system.web>
</configuration>
From the code in Listing 15-4, which is placed within theweb.configfile, you can see that two groups
are listed The first group is theMemberDetailsgroup, which has four specific items defined; the second group —FamilyDetails— has three other related items defined Personalization groups are defined
using the<group>element within the<properties>definition The name of the group is specified
using thenameattribute, just as you specify the<add>element You can have as many groups defined as you deem necessary or as have been recommended as good practice to employ
Using Grouped Personalization Properties
From Listing 15-4, you can also see that some items are not defined in any particular group It is possible
to mix properties defined from within a group with those that are not The items not defined in a group
in Listing 15-4 can still be accessed in the manner illustrated previously:
Label1.Text = Profile.FirstName
Now, concerning working with personalization groups, you can access your defined items in a logical
manner using nested namespaces:
Label1.Text = Profile.MemberDetails.DateJoined
Label2.Text = Profile.FamilyDetails.MarriedStatus
From this example, you can see that two separate items from each of the defined personalization groups were accessed in a logical manner When you study the defined properties in theweb.configfile of
your application, you can see that each of the groups in the example has a property with the same
name —Location This is possible because they are defined using personalization groups With this
structure, it is now possible to get at each of theLocationproperties by specifying the appropriate group:
Label1.Text = Profile.MemberDetails.Location
Label2.Text = Profile.FamilyDetails.Location
Defining Types for Personalization Properties
By default, when you store personalization properties, these properties are created as typeSystem
String It is quite easy, however, to change the type to another type altogether through configuration
settings within theweb.configfile To define the name of the personalization property along with its
appropriate type, you use thetypeattribute of the<add>element contained within the<properties>
section, as shown in Listing 15-5
Listing 15-5: Defining types for personalization properties
<properties>
<add name="FirstName" type="System.String" />
Continued
Trang 6<add name="LastName" type="System.String" />
<add name="LastVisited" type="System.DateTime" />
<add name="Age" type="System.Int32" />
<add name="Member" type="System.Boolean" />
</properties>
The first two properties,FirstNameandLastName, are cast as typeSystem.String This is not actually
required Even if you omitted this step, they would still be cast as typeStringbecause that is the default
type of any property defined in the personalization system (if no other type is defined) The next
person-alization property is theLastVisitedproperty, which is defined as typeSystem.DateTimeand used to
store the date and time of the end user’s last visit to the page Beyond that, you can see the rest of the
personalization properties are defined using a specific NET data type
This is the preferred approach because it gives you type-checking capabilities as you code your
applica-tion and use the personalizaapplica-tion properties you have defined
Using Custom Types
As you can see from the earlier examples that show you how to define types for the personalization
properties, it is quite simple to define properties and type cast them to particular data types that are
available in the NET Framework Items such asSystem.Integer,System.String,System.DateTime,
System.Byte, andSystem.Booleanare easily defined within theweb.configfile But how do you go
about defining complex types?
Personalization properties that utilize custom types are just as easy to define as personalization properties
that use simple types Custom types give you the capability to store complex items such as shopping cart
information or other status information from one use of the application to the next Listing 15-6 first
shows a class,ShoppingCart, which you use later in one of the personalization property definitions
Listing 15-6: Creating a class to use as a personalization type
VB
<Serializable()> _
Public Class ShoppingCart
Private PID As String
Private CompanyProductName As String
Private Number As Integer
Private Price As Decimal
Private DateAdded As DateTime
Public Property ProductID() As String
Get Return PID End Get Set(ByVal value As String) PID = value
End Set End Property
Public Property ProductName() As String
Trang 7Return CompanyProductName
End Get
Set(ByVal value As String)
CompanyProductName = value
End Set
End Property
Public Property NumberSelected() As Integer
Get
Return Number
End Get
Set(ByVal value As Integer)
Number = value
End Set
End Property
Public Property ItemPrice() As Decimal
Get
Return Price
End Get
Set(ByVal value As Decimal)
Price = value
End Set
End Property
Public Property DateItemAdded() As DateTime
Get
Return DateAdded
End Get
Set(ByVal value As DateTime)
DateAdded = value
End Set
End Property
End Class
C#
using System;
[Serializable]
public class ShoppingCart
{
private string PID;
private string CompanyProductName;
private int Number;
private decimal Price;
private DateTime DateAdded;
public ShoppingCart() {}
public string ProductID
{
get {return PID;}
set {PID = value;}
}
Continued
Trang 8public string ProductName
{
get { return CompanyProductName; } set { CompanyProductName = value; } }
public int NumberSelected
{
get { return Number; } set { Number = value; } }
public decimal ItemPrice
{
get { return Price; } set { Price = value; } }
public DateTime DateItemAdded
{
get { return DateAdded; } set { DateAdded = value; } }
}
This simple shopping cart construction can now store the end user’s shopping cart basket as the user
moves around on an e-commerce site The basket can even be persisted when the end user returns to the
site at another time Be sure to note that the class requires aSerializableattribute preceding the class
declaration to ensure proper transformation to XML or binary
Look at how you would specify from within theweb.configfile that a personalization property is this
complex type, such as aShoppingCarttype This is illustrated in Listing 15-7
Listing 15-7: Using complex types for personalization properties
<properties>
<add name="FirstName" type="System.String" />
<add name="LastName" type="System.String" />
<add name="LastVisited" type="System.DateTime" />
<add name="Age" type="System.Int32" />
<add name="Member" type="System.Boolean" />
<add name="Cart" type="ShoppingCart" serializeAs="Binary" />
</properties>
Just as the basic data types are stored in the personalization data stores, this construction allows you to
easily store custom types and to have them serialized into the end data store in the format you choose
In this case, theShoppingCartobject is serialized as a binary object into the data store TheSerializeAs
attribute can take the values defined in the following list:
❑ Binary:Serializes and stores the object as binary data within the chosen data store
❑ ProviderSpecific:Stores the object based upon the direction of the provider This simply means
Trang 9❑ String:The default setting Stores the personalization properties as a string inside the chosen
data store
❑ XML:Takes the object and serializes it into an XML format before storing it in the chosen
data store
Providing Default Values
In addition to defining the data types of the personalization properties, you can also define their default values directly in theweb.configfile By default, the personalization properties you create do not have
a value, but you can easily change this using thedefaultValueattribute of the<add>element Defining default values is illustrated in Listing 15-8
Listing 15-8: Defining default values for personalization properties
<properties>
<add name="FirstName" type="System.String" />
<add name="LastName" type="System.String" />
<add name="LastVisited" type="System.DateTime" />
<add name="Age" type="System.Integer" />
<add name="Member" type="System.Boolean" defaultValue="false" />
</properties>
From this example, you can see that only one of the personalization properties is provided with a default value The last personalization property,Memberin this example, is given a default value offalse This means that when you add a new end user to the personalization property database,Memberis defined
instead of remaining a blank value within the system
Making Personalization Properties Read-Only
It is also possible to make personalization properties read-only To do this, you simply add thereadOnly
attribute to the<add>element:
<add name="StartDate" type="System.DateTime" readOnly="true" />
To make the personalization property a read-only property, you give thereadOnlyattribute a value of
true By default, this property is set tofalse
Anonymous Personalization
A great feature in ASP.NET enables anonymous end users to utilize the personalization features it
provides This is important if a site requires registration of some kind In these cases, end users do not
always register for access to the greater application until they have first taken advantage of some of the basic services For instance, many e-commerce sites allow anonymous end users to shop a site and use
the site’s shopping cart before the shoppers register with the site
Trang 10Enabling Anonymous Identification of the End User
By default, anonymous personalization is turned off because it consumes database resources on popular
sites Therefore, one of the first steps in allowing anonymous personalization is to turn on this feature
using the appropriate setting in theweb.configfile You also need to make some changes regarding
how the properties are actually defined in theweb.configfile and to determine if you are going to allow
anonymous personalization for your application
As shown in Listing 15-9, you can turn on anonymous identification to enable the personalization engine
to identify the unknown end users using the<anonymousIdentification>element
Listing 15-9: Allowing anonymous identification
<configuration>
<system.web>
<anonymousIdentification enabled="true" />
</system.web>
</configuration>
To enable anonymous identification of the end users who might visit your applications, you add an
<anonymousIdentification>element to theweb.configfile within the<system.web>nodes Then
within the<anonymousIdentification>element, you use theenabledattribute and set its value to
true Remember that by default, this value is set tofalse
When anonymous identification is turned on, ASP.NET uses a unique identifier for each anonymous user
who comes to the application This identifier is sent with each and every request, although after the end
user becomes authenticated by ASP.NET, the identifier is removed from the process
For an anonymous user, information is stored by default as a cookie on the end user’s machine
Addi-tional information (the personalization properties that you enable for anonymous users) is stored in the
specified data store on the server
To see this in action, turn off the Windows Authentication for your example application and, instead, use
Forms Authentication This change is demonstrated in Listing 15-10
Listing 15-10: Turning off Windows Authentication and using Forms Authentication
<configuration>
<system.web>
<anonymousIdentification enabled="true" />
<authentication mode="Forms" />
</system.web>
</configuration>
With this in place, if you run the page from the earlier example in Listing 15-2, you see the header
pre-sented in Listing 15-11