- •Contents
- •Introduction
- •Acknowledgments
- •The Goals of ASP.NET 2.0
- •Developer productivity
- •Administration and management
- •Performance and scalability
- •Device-specific code generation
- •Additional New Features of ASP.NET 2.0
- •New developer infrastructures
- •New compilation system
- •Additions to the page framework
- •New objects for accessing data
- •New server controls
- •A New IDE for Building ASP.NET 2.0 Pages
- •The Document Window
- •Views in the Document Window
- •The tag navigator
- •Page tabs
- •Code change status notifications
- •Error notifications and assistance
- •The Toolbox
- •The Solution Explorer
- •Lost Windows
- •Other Common Visual Studio Activities
- •Creating new projects
- •Making references to other objects
- •Using smart tags
- •Saving and importing Visual Studio settings
- •Application Location Options
- •Built-in Web server
- •Web site requiring FrontPage Extensions
- •The ASP.NET Page Structure Options
- •Inline coding
- •New code-behind model
- •New Page Directives
- •New attributes
- •New directives
- •New Page Events
- •Cross-Page Posting
- •New Application Folders
- •\Code folder
- •\Themes folder
- •\Resources folder
- •Compilation
- •The New Data Source Controls
- •The SqlDataSource and GridView Controls
- •Reading data
- •Applying paging in the GridView
- •Sorting rows in the GridView control
- •Defining bound columns in the GridView control
- •Enabling the editing of rows in the GridView control
- •Deleting data from the GridView
- •Dealing with other column types in the GridView
- •Selecting which fields to display in the DetailsView control
- •Using the GridView and DetailsView together
- •Updating, inserting, and deleting rows
- •XmlDataSource Control
- •ObjectDataSource Control
- •SiteMapDataSource Control
- •DataSetDataSource Control
- •Visual Studio 2005
- •Connection Strings
- •Site Maps
- •The PathSeparator property
- •The PathDirection property
- •The ParentLevelsDisplayed property
- •The ShowToolTips property
- •Examining the parts of the TreeView control
- •Binding the TreeView control to an XML file
- •Selecting multiple options in a TreeView
- •Specifying custom icons in the TreeView control
- •Specifying lines used to connect nodes
- •Working with the TreeView control programmatically
- •Applying different styles to the Menu control
- •Menu Events
- •Binding the Menu control to an XML file
- •SiteMap Data Provider
- •SiteMapViewType
- •StartingNodeType
- •SiteMap API
- •Why Do You Need Master Pages?
- •The Basics of Master Pages
- •Coding a Master Page
- •Coding a Content Page
- •Mixing page types and languages
- •Specifying which master page to use
- •Working with the page title
- •Working with controls and properties from the master page
- •Nesting Master Pages
- •Container-Specific Master Pages
- •Event Ordering
- •Caching with Master Pages
- •Using ASP.NET 2.0 Packaged Themes
- •Applying a theme to a single ASP.NET page
- •Applying a theme to an entire application
- •Applying a theme to all applications on a server
- •Removing themes from server controls
- •Removing themes from Web pages
- •Removing themes from applications
- •Creating Your Own Themes
- •Creating the proper folder structure
- •Creating a skin
- •Including CSS files in your themes
- •Having your themes include images
- •Defining Multiple Skin Options
- •Programmatically Working with Themes
- •Themes and Custom Controls
- •Authentication
- •Authorization
- •ASP.NET 2.0 Authentication
- •Setting up your Web site for membership
- •Adding users
- •Asking for credentials
- •Working with authenticated users
- •Showing the number of users online
- •Dealing with passwords
- •ASP.NET 2.0 Authorization
- •Using the LoginView server control
- •Setting up your Web site for role management
- •Adding and retrieving application roles
- •Deleting roles
- •Adding users to roles
- •Getting all the users of a particular role
- •Getting all the roles of a particular user
- •Removing users from roles
- •Checking users in roles
- •Using the Web Site Administration Tool
- •The Personalization Model
- •Adding a simple personalization property
- •Using personalization properties
- •Adding a group of personalization properties
- •Using grouped personalization properties
- •Defining types for personalization properties
- •Using custom types
- •Providing default values
- •Making personalization properties read-only
- •Anonymous Personalization
- •Enabling anonymous identification of the end user
- •Working with anonymous identification events
- •Anonymous options for personalization properties
- •Migrating Anonymous Users
- •Personalization Providers
- •Working with the Access personalization provider
- •Working with the SQL Server personalization provider
- •Using multiple providers
- •Building Dynamic and Modular Web Sites
- •Introducing the WebPartManager control
- •Working with zone layouts
- •Understanding the WebPartZone control
- •Explaining the WebPartPageMenu control
- •Modifying zones
- •Caching in ASP.NET 1.0/1.1
- •Output caching
- •Partial page caching
- •Data caching using the Cache object
- •Cache dependencies
- •ASP.NET 2.0 unseals the CacheDependency class
- •Enabling databases for SQL Server cache invalidation
- •Enabling tables for SQL Server cache invalidation
- •Looking at SQL Server
- •Looking at the tables that are enabled
- •Disabling a table for SQL Server cache invalidation
- •Disabling a database for SQL Server cache invalidation
- •Configuring your ASP.NET Application
- •Adding more than one table to a page
- •Attaching SQL Server cache dependencies to the Request object
- •Attaching SQL Server cache dependencies to the Cache object
- •Customizing the side navigation
- •Examining the AllowReturn attribute
- •Working with the StepType attribute
- •Adding a header to the Wizard control
- •Utilizing Wizard control events
- •Working with images from disk
- •Resizing images
- •Displaying images from streams
- •The MMC ASP.NET Snap-In
- •General
- •Custom Errors
- •Authorization
- •Authentication
- •Application
- •State Management
- •Advanced
- •ASP.NET Web Site Administration Tool
- •Home
- •Security
- •Profile
- •Application
- •Provider
- •Managing the Site Counter System
- •Generics
- •Iterators
- •Anonymous Methods
- •Operator Overloading
- •Visual Basic XML Documentation
- •New Visual Basic Keywords
- •Continue
- •Using
- •Global
- •Index
Chapter 9
Adding a group of personalization properties
If you want to store a large number of personalization properties about a particular user, remember, 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 9-4.
Listing 9-4: Creating personalization groups in the web.config file
<configuration>
<system.web>
<profile inherits=”System.Web.Profile.HttpProfileBase, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”>
<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>
</profile>
</system.web>
</configuration>
From the code in Listing 9-4, which is placed within the web.config file, you can see that two groups are listed. The first group is the MemberDetails group, which has four specific items defined; the second group — FamilyDetails — has three other related items defined. Personalization groups are
270
Personalization
defined using the <group> element within the <properties> definition. The name of the group is specified using the name attribute, 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 9-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 9-4 can still be accessed in the manner illustrated previously:
Label1.Text = Profile.FirstName
Now, using 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 that were defined were accessed in a logical manner. From the defined properties, you can see that each of the groups has a property with the same name — Location. This is possible because you are using personalization groups. With this structure, it is now possible to get at each of the Location properties 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, you store them as type String. It is quite easy, however, to change the type to something else through configurations within the web.config file. To define the name of the personalization property along with its type, you use the Type attribute, as shown in Listing 9-5.
Listing 9-5: Defining 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.Integer” />
<add name=”Member” type=”System.Boolean” />
</properties>
271
Chapter 9
The first two properties, FirstName and LastName, are cast as type String. This isn’t actually required. Even if you omitted this step, they would still be cast as type String because that is the default type. The next personalization property is the LastVisited property, which is defined as type System.DataTime and 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 application and use the personalization properties you have defined.
Using custom types
As you can see from the examples that show you how to define types for the personalization properties, it is quite simple to define types that are available in the .NET Framework. Items such as System.Integer,
System.String, System.DateTime, System.Byte, and System.Boolean are easily defined within the web.config file. 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 9-6 first shows a class, ShoppingCart, which you use later in one of the personalization property definitions.
Listing 9-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
Get
Return CompanyProductName
End Get
Set(ByVal value As String)
CompanyProductName = value
End Set
End Property
Public Property NumberSelected() As Integer
Get
272
Personalization
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; }
}
public string ProductName
{
get { return CompanyProductName; } set { CompanyProductName = value; }
}
public int NumberSelected
{
get { return Number; }
(continued)
273
Chapter 9
Listing 9-6: (continued)
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 she moves around on an e-commerce site. The basket can even be persisted when the end user returns to the site at another time.
Take a look at how you would specify from within the web.config file that a personalization property is this complex type. This is illustrated in Listing 9-7.
Listing 9-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.Integer” />
<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, the ShoppingCart object is serialized into a binary object in the data store. The SerializeAs 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 that instead of the personalization engine determining the serialization of the object, it is simply left up to the data store.
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.
274
