Programming Microsoft ASP.NET 2.0 Core Reference

 

The Session's State

The HttpSessionState class provides a dictionary-based model of storing and retrieving sessionstate values. Unlike HttpApplicationState, this class doesn't expose its contents to all users operating on the virtual directory at a given time. Only the requests that originate in the context of the same session that is, generated across multiple page requests made by the same user can access the session state. The session state can be stored and published in a variety of ways, including in a Web farm or Web garden scenario. By default, though, the session state is held within the ASP.NET worker process.

Compared to Session, the intrinsic object of ASP, the ASP.NET session state is nearly identical in use, but it's significantly richer in functionality and radically different in architecture. In addition, it provides some extremely handy facilities such as support for cookieless browsers, Web farms, and Web gardens and the capability of being hosted by external processes, including Microsoft SQL Server. In this way, ASP.NET session management can provide an unprecedented level of robustness and reliability.

In ASP.NET 2.0, developers can create custom data stores for session state. For example, if you need the robustness that a database-oriented solution can guarantee, but you work with Oracle databases, you need not install SQL Server as well. By writing a piece of additional code, you can support an Oracle session data store while using the same Session semantics and classes.

The extensibility model for session state offers two options: customizing bits and pieces of the existing ASP.NET session-state mechanism (for example, creating an Oracle session provider or a module controlling the generation of the ID) and replacing the standard session-state HTTP module with a new one. The former option is easier to implement but provides a limited set of features you can customize. The latter option is more complicated to code but provides the greatest flexibility.

The Session-State HTTP Module

Regardless of the internal implementation, the programmer's API for session-state management is just one the old acquaintance known as the Session object. It was a COM object in classic ASP that was instantiated in the asp.dll ISAPI extension and injected in the memory space of the ActiveX Scripting engine called to parse and process the .asp script. It is a collection object in ASP.NET, living behind the Session property of the Page class. The exact type is HttpSessionState; it's a class that's not further inheritable and which implements ICollection and IEnumerable. An instance of this class is created during the startup of each request that requires session support. The collection is filled with name/value pairs read from the specified medium and attached to the context of the request the HttpContext class. The Page's Session property just mirrors the Session property of the HttpContext class.

If developers can simply work with one object the Session object regardless of other details, most of the credit goes to an HTTP module that governs the process of retrieving and storing session state with some help from special provider objects. The ASP.NET module in charge of setting up the session state for each user connecting to an application is an HTTP module named SessionStateModule. Structured after the IHttpModule interface, the SessionStateModule object provides session-state services for ASP.NET applications.

Although as an HTTP module it is required to supply a relatively simple programming interface the IHttpModule interface contracts only for Init and Dispose methods SessionStateModule does perform a number of quite sophisticated tasks, most of which are fundamental for the health and functionality of the Web application. The session-state module is invoked during the setup of the HttpApplication object that will process a given request and is responsible for either generating or obtaining a unique session ID string and for storing and retrieving state data from a state provider for example, SQL Server or the Web server's memory.

State Client Managers

When invoked, the session-state HTTP module reads the settings in the <sessionState> section of the web.config file and determines what the expected state client manager is for the application. A state client manager is a component that takes care of storing and retrieving data of all currently active sessions. The SessionStateModule component queries the state client manager to get the name/value pairs of a given session.

In ASP.NET 2.0, there are four possibilities for working with the session state. The session state can be stored locally in the ASP.NET worker process; the session state can be maintained in an external, even remote, process named aspnet_state.exe; the session state can be managed by SQL Server and stored in an ad hoc database table. Finally, a fourth option is added in ASP.NET 2.0 and entails storing the sessions in a custom component. Table 13-4 briefly discusses the various options.

Table 13-4: State Client Providers

Mode

Description

Custom

The values for all the sessions are stored in a custom data store. Not available in ASP.NET 1.x.

InProc

The values for all the sessions are maintained as live objects in the memory of the ASP.NET worker process (aspnet_wp.exe or w3wp.exe in Microsoft Windows Server 2003). This is the default option.

Off

Session state is disabled, and no state client provider is active.

SQLServer

The values for all the sessions are serialized and stored in a SQL Server table. The instance of SQL Server can run either locally or remotely.

StateServer

The values for all the sessions are serialized and stored in the memory of a separate system process (aspnet_state.exe). The process can also run on another machine. Session values are deserialized into the session dictionary at the beginning of the request. If the request completes successfully, state values are serialized into the process memory and made available to other pages.

The SessionStateMode enum type lists the available options for the state client provider. The InProc option is by far the fastest possible in terms of access. However, bear in mind that the more data you store in a session, the more memory is consumed on the Web server, thereby increasing the risk of performance hits. If you plan to use any of the out-of-process solutions, the possible impact of serialization and deserialization should be carefully considered. We'll discuss this aspect in detail later in the chapter, starting with the "Persist Session Data to Remote Servers" section.

The session-state module determines the state provider to use based on what it reads out of the <sessionState> section of the web.config file. Next, it instantiates and initializes the state provider for the application. Each provider continues its own initialization, which is quite different depending on the type. For example, the SQL Server state manager opens a connection to the given database, whereas the out-of-process manager checks the specified TCP port. The InProc state manager, on the other hand, stores a reference to the callback function that will be used to fire the Session_End event. (I'll discuss this further in the section "Lifetime of a Session.")

All state providers expose a common set of methods to communicate with the caller. The schema is outlined in Figure 13-1.

Figure 13-1: SessionStateModule and its child-state client managers.

Note 

In ASP.NET 2.0, all the actual state provider objects derive from a base class SessionStateStoreProviderBase. In ASP.NET 1.x, on the other hand, all state providers implement a common interface, named IStateClientManager. This interface has been lost in the transition to version 2.0, a victim of the refactoring process and the advent of the provider model. (See Chapter 1.) However, the switch to base classes from interfaces is a pervasive design choice that affects all of ASP.NET Framework 2.0.

Creating the HttpSessionState Object

The state module is responsible for retrieving and attaching the session state to the context of each request that runs within the session. The session state is available only after the HttpApplication.AcquireRequestState event fires, and it gets irreversibly lost after the HttpApplication.ReleaseRequestState event. Subsequently, this means that no state is still available when Session_End fires.

The session module creates the HttpSessionState object for a request while processing the HttpApplication.AcquireRequestState event. At this time, the HttpSessionState object a sort of collection is given its session ID and the session dictionary. The session dictionary is the actual collection of state values that pages will familiarly access through the Session property.

If a new session is being started, such a data dictionary is simply a newly created empty object. If the module is serving a request for an existing session, the data dictionary will be filled by deserializing the contents supplied by the currently active session-state provider. At the end of the request, the current content of the dictionary, as modified by the page request, is flushed back to the state provider through a serialization step. The whole process is depicted in Figure 13-2.

Figure 13-2: The session-state management timeline.

Synchronizing Access to the Session State

So when your Web page makes a call into the Session property, it's actually accessing a local, in-memory copy of the data. What if other pages (in the same session) attempt to concurrently access the session state? In that case, the current request might end up working on inconsistent data or data that isn't up to date.

To avoid that, the session-state module implements a reader/writer locking mechanism and queues the access to state values. A page that has session-state write access will hold a writer lock on the session until the request finishes. A page gains write access to the session state by setting the EnableSessionState attribute on the @Page directive to true. A page that has sessionstate read access for example, when the EnableSessionState attribute is set to ReadOnly will hold a reader lock on the session until the request finishes.

If a page request sets a reader lock, other concurrently running requests cannot update the session state but are allowed to read. If a page request sets a writer lock on the session state, all other pages are blocked regardless of whether they have to read or write. For example, if two frames attempt to write to Session, one of them has to wait until the other finishes. Figure 13-3 shows the big picture.

Figure 13-3: Page access to the session state is synchronized, and a serialization/deserialization layer ensures that each request is served an up-to-date dictionary of values, stored at the application's convenience.

Tip 

Concurrent access to the session state is not very common in reality. It might happen if you have a multiframe page or if your users work with two copies of the same page or multiple pages of the same application at the same time. It also happens when you use session-enabled HTTP handlers to serve embedded resources such as images or CSS files. By default, you are protected against concurrent accesses. However, declaring the exact use of the session state that a page is going to make (read/write, read-only, or no use) is an excellent form of optimization. You do this through the EnableSessionState attribute on the @Page directive.

Properties of the HttpSessionState Class

The HttpSessionState class is defined in the System.Web.SessionState namespace. It is a generic collection class and implements the ICollection interface. The properties of the HttpSessionState class are listed in Table 13-5.

Table 13-5: HttpSessionState Properties

Property

Description

CodePage

Gets or sets the code page identifier for the current session.

Contents

Returns a reference to this object. Provided for ASP compatibility.

CookieMode

Details the application's configuration for cookieless sessions. Declared to be of type HttpCookieMode. (I'll discuss this in more detail later.) Not available in ASP.NET 1.x.

Count

Gets the number of items currently stored in the session state.

IsCookieless

Indicates whether the session ID is embedded in the URL or stored in an HTTP cookie. IsCookieless is more specific than CookieMode.

IsNewSession

Indicates whether the session was created with the current request.

IsReadOnly

Indicates whether the session is read-only. The session is read-only if the EnableSessionState attribute on the @Page directive is set to the keyword ReadOnly.

IsSynchronized

Returns false. (See references to this later in the chapter.)

Item

Indexer property, provides read/write access to a session-state value. The value can be specified either by name or index.

Keys

Gets a collection of the keys of all values stored in the session.

LCID

Gets or sets the locale identifier (LCID) of the current session.

Mode

Gets a value denoting the state client manager being used. Acceptable values are listed in Table 13-4.

SessionID

Gets a string with the ID used to identify the session.

StaticObjects

Gets a collection including all instances of all objects declared in global.asax using an <object> tag with the scope attribute set to Session. Note that you cannot add objects to this collection from within an ASP.NET application that is, programmatically.

SyncRoot

Returns a reference to this object. (See references to this later in the chapter.)

Timeout

Gets or sets the minutes that the session module should wait between two successive requests before terminating the session.

The HttpSessionState class is a normal collection class because it implements the ICollection interface, but synchronization-wise it is a very special collection class. As mentioned, the synchronization mechanism is implemented in the SessionStateModule component, which guarantees that at most one thread will ever access the session state. However, because HttpSessionState implements the ICollection interface, it must provide an implementation for both IsSynchronized and SyncRoot. Notice that IsSynchronized and SyncRoot are collection-specific properties for synchronization and have nothing to do with the session synchronization discussed previously. They refer to the ability of the collection class (HttpSessionState in this case) to work synchronistically. Technically speaking, the HttpSessionState is not synchronized, but access to session state is.

Methods of the HttpSessionState Class

Table 13-6 shows all the methods available in the HttpSessionState class. They mostly have to do with the typical operations on a collection. In this sense, the only exceptional method is Abandon, which causes the session to be canceled.

Table 13-6: HttpSessionState Methods

Method

Description

Abandon

Sets an internal flag that instructs the session module to cancel the current session.

Add

Adds a new item to the session state. The value is boxed in an object type.

Clear

Clears all values from the session state.

CopyTo

Copies the collection of session-state values to a one-dimensional array, starting at the specified index in the array.

GetEnumerator

Gets an enumerator to loop through all the values in the session.

Remove

Deletes an item from the session-state collection. The item is identified by the key.

RemoveAll

Calls Clear.

RemoveAt

Deletes an item from the session-state collection. The item is identified by position.

When running the procedure to terminate the current request, the session-state module checks an internal flag to verify whether the user ordered that the session be abandoned. If the flag is set that is, the Abandon method was called any response cookie is removed and the procedure to terminate the session is begun. Notice, though, that this does not necessarily mean that a Session_End event will fire.

First, the Session_End event fires only if the session mode is InProc; second, the event does not fire if the session dictionary is empty and no real session state exists for the application. In other words, at least one request must have been completed for the Session_End to fire when the session is closed either naturally or after a call to Abandon.

 

Категории