
- •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

Personalization
Providing default values
In addition to defining the types of personalization properties, you can also define their default values. The personalization properties you create do not have a value, but you can easily change this using the DefaultValue attribute of the <add> element. Defining default values is illustrated in Listing 9-8.
Listing 9-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, Member, in this example, is given a default value of False. This means that when you add a new end user to the personalization property database, Member is defined instead of remaining a blank value.
Making personalization properties read-only
It is also possible to make personalization properties read-only. To do this, you simply add the readOnly attribute to the <add> element:
<add name=”StartDate” type=”System.DateTime” readOnly=”True” />
To make the personalization property a read-only property, you give the readOnly attribute a value of True. By default, this property is set to False.
Anonymous Personalization
A great new feature in ASP.NET 2.0 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.
Enabling 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 to allow anonymous personalization is to turn on this feature using a setting in the web.config file.
275

Chapter 9
As shown in Listing 9-9, you can turn on anonymous identification to enable the personalization engine to identify the unknown end users.
Listing 9-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 the web.config file within the <system.web> nodes. Then within the <anonymousIdentification> element, you use the Enabled attribute and set its value to True. Remember that by default, this value is set to False.
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. Additional information (the personalization properties that you enable for anonymous users) is stored in the specified data store on the server.
Changing the name of the cookie for anonymous identification
Cookies are used by default under the cookie name .ASPXANONYMOUS. You can change the name of this cookie from the <anonymousIdentification> element in the web.config file by using the cookieName attribute, as shown in Listing 9-10.
Listing 9-10: Changing the name of the cookie
<configuration>
<system.web>
<anonymousIdentification
enabled=”True” cookieName=”.ASPXEvjenWebApplication” />
</system.web>
</configuration>
Changing the length of time the cookie is stored
Also, by default, the cookie stored on the end user’s machine is stored for 100,000 minutes (which is almost 70 days). If you want to change this value, you do it within this <anonymousIdentification> element through the use of the cookieTimeout attribute, as shown in Listing 9-11.
276

Personalization
Listing 9-11: Changing the length of time the cookie is stored
<configuration>
<system.web>
<anonymousIdentification
enabled=”True” cookieTimeout=”1440” />
</system.web>
</configuration>
In this case, I changed the cookieTimeout value to 1440 — meaning 1,440 minutes (or one day). This would be ideal for a shopping cart for which you don’t want to persist the identification of the end user too long.
Changing how the identifiers are stored
Although anonymous identifiers are stored through the use of cookies, you can also easily change this. Cookies are, by far, the preferred way to achieve identification, but you can also do it without the use of cookies. Other options include using the URI or device profiles. Listing 9-12 shows an example of using the URI to place the identifiers.
Listing 9-12: Specifying how cookies are stored
<configuration>
<system.web>
<anonymousIdentification
enabled=”True” cookieless=”UseUri” />
</system.web>
</configuration>
Besides UseUri, other options include UseCookies, AutoDetect, and UseDeviceProfile. The following list reviews each of the options:
UseCookies: This is the default setting. If you set no value, ASP.NET assumes this is the value. UseCookies means that a cookie is placed on the end user’s machine for identification.
UseUri: This value means that a cookie will not be stored on the end user’s machine, but instead the unique identifier will be munged within the URL of the page. This is the same approach used for cookieless sessions in ASP.NET 1.0/1.1. Although this is great if developers want to avoid sticking a cookie on an end user’s machine, it does create strange looking URLs and can be an issue when an end user bookmarks pages for later retrieval.
AutoDetect: Using this value means that you are letting the ASP.NET engine decide whether to use cookies or use the URL-approach for the anonymous identification. This is done on a peruser basis and performs a little worse than the other two options. ASP.NET must check the end user before deciding which approach to use. My suggestion is to use AutoDetect instead of
277

Chapter 9
UseUri if you absolutely must allow for end users who have cookies turned off (which is rare these days).
UseDeviceProfile: Configures the identifier for the device or browser that is making the request.
Looking at how the anonymous identifiers are stored
In order to make the anonymous identifiers unique, a globally unique GUID is used. You can also now grab hold of this unique identifier for your own use. In order to retrieve the GUID, the Request object has been enhanced with an AnonymousId property. The AnonymousId property returns a value of type String, which can be used in your code as shown here:
Label1.Text = Request.AnonymousId
Working with anonymous identification events
In working with the creation of anonymous users, be aware of two important events that can be used for managing the process:
AnonymousIdentification_OnCreate
AnonymousIdentification_OnRemove
By using the AnonymousIdentification_OnCreate event, you can work with the identification of the end user as it occurs. For instance, if you do not want to use GUIDs for uniquely identifying the end user, you can change the identifying value from this event instead.
To do so, create the event using the event delegate of type AnonymousIdentificationEventArgs, as illustrated in Listing 9-13.
Listing 9-13: Changing the unique identifier of the anonymous user
VB
Public Sub AnonymousIdentification_OnCreate(ByVal sender As Object, _ ByVal e As AnonymousIdentificationEventArgs)
e.AnonymousId = “Bubbles “ & DateTime.Now()
End Sub
C#
public void AnonymousIdentification_OnCreate(object sender, AnonymousIdentificationEventArgs e)
{
e.AnonymousId = “Bubbles “ + DateTime.Now();
}
The AnonymousIdentificationEventArgs event delegate exposes an AnonymousId property that assigns the value used to uniquely identify the anonymous user. Now, instead of a GUID to uniquely identify the anonymous user as
d13fafec-244a-4d21-9137-b213236ebedb
278