The page in Listing 28.24 illustrates how you modify a Profile property when Anonymous Identification is enabled... For example, the MigrateAnonymous event handler in Listing 28.25 autom
Trang 1LISTING 28.23 Web.Config
<?xml version=”1.0”?>
<configuration>
<system.web>
<authentication mode=”Forms” />
<anonymousIdentification enabled=”true” />
<profile>
<properties>
<add
name=”numberOfVisits”
type=”Int32”
defaultValue=”0”
allowAnonymous=”true” />
</properties>
</profile>
</system.web>
</configuration>
The numberOfVisits property defined in Listing 28.23 includes the allowAnonymous
attribute The web configuration file also enables Forms authentication When Forms
authentication is enabled, and you don’t log in, you are an anonymous user
The page in Listing 28.24 illustrates how you modify a Profile property when
Anonymous Identification is enabled
LISTING 28.24 ShowAnonymousIdentification.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
void Page_PreRender()
{
lblUserName.Text = Profile.UserName;
lblIsAnonymous.Text = Profile.IsAnonymous.ToString();
Profile.numberOfVisits++;
lblNumberOfVisits.Text = Profile.numberOfVisits.ToString();
}
Trang 2protected void btnLogin_Click(object sender, EventArgs e)
{
FormsAuthentication.SetAuthCookie(“Bob”, false);
Response.Redirect(Request.Path);
}
protected void btnLogout_Click(object sender, EventArgs e)
{
FormsAuthentication.SignOut();
Response.Redirect(Request.Path);
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Show Anonymous Identification</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
User Name:
<asp:Label
id=”lblUserName”
Runat=”server” />
<br />
Is Anonymous:
<asp:Label
id=”lblIsAnonymous”
Runat=”server” />
<br />
Number Of Visits:
<asp:Label
id=”lblNumberOfVisits”
Runat=”server” />
<hr />
<asp:Button
id=”btnReload”
Text=”Reload”
Runat=”server” />
<asp:Button
id=”btnLogin”
Text=”Login”
Trang 3Runat=”server” />
<asp:Button
id=”btnLogout”
Text=”Logout”
OnClick=”btnLogout_Click”
Runat=”server” />
</div>
</form>
</body>
</html>
Each time that you request the page in Listing 28.24, the numberOfVisits Profile
prop-erty is incremented and displayed The page includes three buttons: Reload, Login, and
Logout (see Figure 28.8)
FIGURE 28.8 Creating an anonymous profile
The page also displays the value of the Profile.UserName property This property
repre-sents either the current username or the anonymous identifier The value of the
numberOfVisits Profile property is tied to the value of the Profile.UserName property
Trang 4You can click the Reload button to quickly reload the page and increment the value of the
numberOfVisits property If you click the Login button, the Profile.UserName property
changes to the value Bob The numberOfVisits property is reset
If you click the Logout button, the Profile.UserName property switches back to your
anonymous identifier The numberOfVisits property reverts to its previous value
Migrating Anonymous Profiles
In the previous section, you saw that all profile information is lost when a user transitions
from anonymous to authenticated For example, if you store a shopping cart in the
Profile object and a user logs in, all the shopping cart items are lost
You can preserve the value of Profile properties when a user transitions from
anony-mous to authenticated by handling the MigrateAnonymous event in the Global.asax file
This event is raised when an anonymous user that has a profile logs in
For example, the MigrateAnonymous event handler in Listing 28.25 automatically copies
the values of all anonymous Profile properties to the user’s current authenticated profile
LISTING 28.25 Global.asax
<%@ Application Language=”C#” %>
<script runat=”server”>
public void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs
➥args)
{
// Get anonymous profile
ProfileCommon anonProfile = Profile.GetProfile(args.AnonymousID);
// Copy anonymous properties to authenticated
foreach (SettingsProperty prop in ProfileBase.Properties)
Profile[prop.Name] = anonProfile[prop.Name];
// Kill the anonymous profile
ProfileManager.DeleteProfile(args.AnonymousID);
AnonymousIdentificationModule.ClearAnonymousIdentifier();
}
</script>
The anonymous Profile associated with the user is retrieved when the user’s anonymous
identifier is passed to the Profile.GetProfile() method Next, each Profile property is
copied from the anonymous Profile to the current Profile Finally, the anonymous
Trang 5anonymous identifier, the MigrateAnonymous event continues to be raised with each page
request after the user authenticates.)
Inheriting a Profile from a Custom Class
Instead of defining a list of Profile properties in the web configuration file, you can
define Profile properties in a separate class For example, the class in Listing 28.26
contains two properties named FirstName and LastName
LISTING 28.26 App_Code\SiteProfile.cs
using System;
using System.Web.Profile;
public class SiteProfile : ProfileBase
{
private string _firstName = “Your First Name”;
private string _lastName = “Your Last Name”;
[SettingsAllowAnonymous(true)]
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
[SettingsAllowAnonymous(true)]
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
}
The class in Listing 28.26 inherits from the BaseProfile class
After you declare a class, you can use it to define a profile by inheriting the Profile object
from the class in the web configuration file The web configuration file in Listing 28.27
uses the inherits attribute to inherit the Profile from the SiteProfile class
Trang 6LISTING 28.27 Web.Config
<?xml version=”1.0”?>
<configuration>
<system.web>
<anonymousIdentification enabled=”true” />
<profile inherits=”SiteProfile” />
</system.web>
</configuration>
After you inherit a Profile in the web configuration file, you can use the Profile in the
normal way You can set or read any of the properties that you defined in the SiteProfile
class by accessing the properties through the Profile object
NOTE
The downloadable code from the website that accompanies this book includes a page
named ShowSiteProfile.aspx, which displays the Profile properties defined in
Listing 28.27
NOTE
If you inherit Profile properties from a class and define Profile properties in the
web configuration file, the two sets of Profile properties are merged
When you define Profile properties in a class, you can decorate the properties with the
following attributes:
SettingsAllowAnonymous—Enables you to allow anonymous users to read and set
the property
ProfileProvider—Enables you to associate the property with a particular Profile
provider
CustomProviderData—Enables you to pass custom data to a Profile provider
For example, both properties declared in the SiteProfile class in Listing 28.27 include
the SettingsAllowAnonymous attribute, which allows anonymous users to read and modify
the properties
Trang 7Creating Complex Profile Properties
To this point, we used the Profile properties to represent simple types such as strings and
integers You can use Profile properties to represent more complex types such as a
custom ShoppingCart class
For example, the class in Listing 28.28 represents a simple shopping cart
LISTING 28.28 App_Code\ShoppingCart.cs
using System;
using System.Collections.Generic;
using System.Web.Profile;
namespace AspNetUnleashed
{
public class ShoppingCart
{
private List<CartItem> _items = new List<CartItem>();
public List<CartItem> Items
{
get { return _items; }
}
}
public class CartItem
{
private string _name;
private decimal _price;
private string _description;
public string Name
{
get { return _name; }
set { _name = value; }
}
public decimal Price
{
get { return _price; }
set { _price = value; }
}
Trang 8public string Description
{
get { return _description; }
set { _description = value; }
}
public CartItem() { }
public CartItem(string name, decimal price, string description)
{
_name = name;
_price = price;
_description = description;
}
}
}
The file in Listing 28.28 actually contains two classes: ShoppingCart and CartItem The
ShoppingCart class exposes a collection of CartItem objects
The web configuration file in Listing 28.29 defines a Profile property named
ShoppingCart that represents the ShoppingCart class The type attribute is set to the fully
qualified name of the ShoppingCart class
LISTING 28.29 Web.Config
<?xml version=”1.0”?>
<configuration>
<system.web>
<profile>
<properties>
<add name=”ShoppingCart” type=”AspNetUnleashed.ShoppingCart” />
</properties>
</profile>
</system.web>
</configuration>
Finally, the page in Listing 28.30 uses the Profile.ShoppingCart property The contents of
the ShoppingCart are bound and displayed in a GridView control The page also contains a
form that enables you to add new items to the ShoppingCart (see Figure 28.9)
Trang 9LISTING 28.30 ShowShoppingCart.aspx
<%@ Page Language=”C#” %>
<%@ Import Namespace=”AspNetUnleashed” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
void Page_PreRender()
{
grdShoppingCart.DataSource = Profile.ShoppingCart.Items;
grdShoppingCart.DataBind();
}
protected void btnAdd_Click(object sender, EventArgs e)
{
CartItem newItem =
new CartItem(txtName.Text, decimal.Parse(txtPrice.Text),
➥txtDescription.Text);
Profile.ShoppingCart.Items.Add(newItem);
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
FIGURE 28.9 Storing a shopping cart in a profile
Trang 10<head id=”Head1” runat=”server”>
<title>Show ShoppingCart</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:GridView
id=”grdShoppingCart”
EmptyDataText=”There are no items in your shopping cart”
Runat=”server” />
<br />
<fieldset>
<legend>Add Product</legend>
<asp:Label
id=”lblName”
Text=”Name:”
AssociatedControlID=”txtName”
Runat=”server” />
<br />
<asp:TextBox
id=”txtName”
Runat=”server” />
<br /><br />
<asp:Label
id=”lblPrice”
Text=”Price:”
AssociatedControlID=”txtPrice”
Runat=”server” />
<br />
<asp:TextBox
id=”txtPrice”
Runat=”server” />
<br /><br />
<asp:Label
id=”lblDescription”
Text=”Description:”
AssociatedControlID=”txtDescription”
Runat=”server” />
<br />
<asp:TextBox
id=”txtDescription”