JavaScript Editor jscript editor     Web designer 



Main Page

Describes a custom session-state store provider implementation and demonstrates implementing a sample provider.

ASP.NET session state is designed to enable you to easily store user session data in different sources for your ASP.NET applications. By default, session state values and information are stored in memory within the ASP.NET process. Alternatively, you can store session data in a state server, which keeps session data in a separate process and retains it if the ASP.NET application is shut down and restarted. Another alternative is to store session data in a SQL Server database, where it can be shared by multiple Web servers.

You can use the supplied session-state stores that are included with ASP.NET, or you can implement your own session-state store provider. The following are the two primary reasons for creating a custom session-state store provider.

You can implement a custom session-state store provider by creating a class that inherits the SessionStateStoreProviderBase class. For more information, see the Required Classes section later in this topic.

The Session State Module

The SessionStateModule calls the session-state store provider to read session data from and write session data to the data store at different times during a request. At the beginning of a request, the SessionStateModule retrieves data from the data source by calling the GetItemExclusive method, or the GetItem method if the EnableSessionState page attribute has been set to ReadOnly. At the end of a request, if the session-state values have been modified, the SessionStateModule calls the System.Web.SessionState.SessionStateStoreProviderBase.SetAndReleaseItemExclusive(System.Web.HttpContext,System.String,System.Web.SessionState.SessionStateStoreData,System.Object,System.Boolean) method to write the updated values to the session-state store. The SessionStateModule calls additional members of the SessionStateStoreProviderBase implementation to initialize a new session as well as delete session data from the data store when the System.Web.SessionState.HttpSessionState.Abandon method is called. Each member of the SessionStateStoreProviderBase class is discussed in more detail in the Required Classes section later in this topic.

The SessionStateModule determines the SessionID value itself, rather than relying on the session-state store provider to do so. You can implement a custom SessionIDModule by creating a class that inherits the ISessionIDManager interface. For more information, see the remarks provided for the ISessionIDManager interface.

The SessionStateManager will revert to the ASP.NET process identity to access any secured resource, such as a database server. You can specify that the SessionStateModule impersonate the identity supplied by IIS by setting the useHostingIdentity attribute of the <sessionState> configuration element to false. For example, if you have configured your IIS application to use Windows Integrated security and you want ASP.NET to impersonate the identity provided by IIS as the identity used for the connection to the data source, then specify <identity impersonate="true" /> in the <system.web> configuration section of the Web.config file for the application and set the useHostingIdentity attribute of the <sessionState> configuration element to false. If the useHostingIdentity attribute is true, then ASP.NET will impersonate the process identity, or the user credentials supplied to the <identity> configuration element, if they exist, when connecting to the data source. For more information on the ASP.NET process identity, see Configuring ASP.NET Process Identity and ASP.NET Impersonation.

Locking Session-Store Data

ASP.NET applications are multithreaded to support responding to multiple concurrent requests. It is possible that multiple concurrent requests may attempt to access the same session information. Consider a scenario where multiple frames in a frameset all access the same application. The separate requests for each frame in the frameset may be executed on the Web server concurrently on different threads. If the ASP.NET pages for each frame source access session-state variables, then you could have multiple threads accessing the session store concurrently. To avoid data collisions at the session store and unexpected session-state behavior, the SessionStateModule and SessionStateStoreProviderBase classes include functionality that exclusively locks the session-store item for a particular session during the execution of an ASP.NET page. Note that no lock is set on a session-store item if the EnableSessionState attribute is marked as ReadOnly. However, other ASP.NET pages in the same application may be able to write to the session store, so a request for read-only session data from the store may still end up waiting for locked data to be freed.

A lock is set on session-store data at the beginning of the request in the call to the System.Web.SessionState.SessionStateStoreProviderBase.GetItemExclusive(System.Web.HttpContext,System.String,System.Boolean,System.TimeSpan,System.Object,System.Web.SessionState.SessionStateActionFlags) method. When the request completes, the lock is released during the call to the System.Web.SessionState.SessionStateStoreProviderBase.SetAndReleaseItemExclusive(System.Web.HttpContext,System.String,System.Web.SessionState.SessionStateStoreData,System.Object,System.Boolean) method.

If the SessionStateModule encounters locked session data during the call to either the GetItemExclusive or GetItem method, it will re-request the session data at half-second intervals until either the lock is released, or the amount of time that the session data has been locked exceeds the value of the ExecutionTimeout property. If the execution time-out is exceeded, the SessionStateModule will call the System.Web.SessionState.SessionStateStoreProviderBase.ReleaseItemExclusive(System.Web.HttpContext,System.String,System.Object) method to free the session-store data and request the session-store data at that time.

Locked session-store data may have been freed by a call to the ReleaseItemExclusive method, on a separate thread, before the call to the SetAndReleaseItemExclusive method for the current response. This could cause the SessionStateModule to set and release session-state store data that has already been released and modified by another session. To avoid this situation, the SessionStateModule includes a lock identifier with each request to modify locked session-store data. Session-store data is only modified if the lock identifier in the data store matches the lock identifier supplied by the SessionStateModule.

Deleting Expired Session-Store Data

When the Abandon method is called for a particular session, the data for that session is deleted from the data store using the RemoveItem method; otherwise the data will remain in the session data store to serve future requests for the session.

The mechanism for deleting expired session data is dependent on the capabilities of your data source. If your data source can be configured to delete expired session data per the session Timeout, you can use the SetItemExpireCallback method to reference the delegate for the Session_OnEnd event and raise it when deleting expired session data.

ApplicationName

To maintain session scope, session-state store providers store session information uniquely for each application. This allows multiple ASP.NET applications to use the same data source without running into a conflict if duplicate session identifiers are encountered.

Because session-state store providers store session information uniquely for each application, you will need to ensure that your data schema, queries, and updates include the application name. For example, the following command is used to retrieve session data from a database.

В CopyCode imageCopy Code
SELECT * FROM Sessions 
  WHERE SessionID = 'ABC123' AND ApplicationName = 'MyApplication'

Alternatively, you can store a combination of the session identifier and the application name as the unique identifier for an item in the session-state data store.

Required Classes

To implement a session-state store provider, create a class that inherits the SessionStateStoreProviderBase abstract class. The SessionStateStoreProviderBase class inherits the ProviderBase abstract class, so you must implement the required members of the ProviderBase class as well. The following tables list the required properties and methods that you must implement from the ProviderBase and SessionStateStoreProviderBase abstract classes and provides a description of each. To view an implementation of each member, see Sample Session-State Store Provider.

Required ProviderBase Members

Member Description

Initialize method

Takes, as input, the name of the provider and a NameValueCollection of configuration settings. This method is used to set property values for the provider instance, including implementation-specific values and options specified in the configuration file (Machine.config or Web.config).

Required SessionStateStoreProvider Members

Member Description

InitializeRequest method

Takes as input the HttpContext for the current request and performs any initialization required by your session-state store provider.

EndRequest method

Takes as input the HttpContext for the current request and performs any cleanup required by your session-state store provider.

Dispose method

Frees any resources no longer in use by the session-state store provider.

GetItemExclusive method

Takes as input the HttpContext for the current request and the SessionID for the current request. Retrieves session values and information from the session data store and locks the session-item data at the data store for the duration of the request. The GetItemExclusive method sets several output-parameter values that inform the calling SessionStateModule about the state of the current session-state item in the data store.

If no session item data is found at the data store, the GetItemExclusive method sets the locked output parameter to false and returns null. This will cause the SessionStateModule to call the CreateNewStoreData method to create a new SessionStateStoreData object for the request.

If session-item data is found at the data store but the data is locked, the GetItemExclusive method sets the locked output parameter to true, sets the lockAge output parameter to the current date and time minus the date and time when the item was locked, sets the lockId output parameter to the lock identifier retrieved from the data store, and returns null. This causes the SessionStateModule to call the GetItemExclusive method again after a half-second interval, to attempt to retrieve the session-item information and obtain a lock on the data. If the value that the lockAge output parameter is set to exceeds the ExecutionTimeout value, then the SessionStateModule will call the ReleaseItemExclusive method to clear the lock on the session-item data and then call the GetItemExclusive method again.

The actionFlags parameter is used with Cookieless sessions when the regenerateExpiredSessionId attribute is set to true. An actionFlags value set to InitializeItem (1) indicates that the entry in the session data store is a new session that requires initialization. Uninitialized entries in the session data store are created by a call to the CreateUninitializedItem method. If the item from the session data store is not an uninitialized item, the actionFlags parameter will be set to zero.

If your provider supports Cookieless sessions, you should set the actionFlags output parameter to the value returned from the session data store for the current item. If the actionFlags parameter value for the requested session-store item equals the InitializeItem enumeration value (1), then the GetItemExclusive method should set the value in the data store to zero after setting the actionFlags out parameter.

GetItem method

This method performs the same work as the GetItemExclusive method, except that it does not attempt to obtain a lock on the session item in the data store. The GetItem method is called when the EnableSessionState attribute is set to ReadOnly.

SetAndReleaseItemExclusive method

Takes as input the HttpContext for the current request, the SessionID for the current request, a SessionStateStoreData object that contains the current session values to be stored, the lock identifier for the current request, and a value that indicates whether the data to be stored is for a new session or an existing session.

If the newItem parameter is true, then the SetAndReleaseItemExclusive method inserts a new item into the data store with the supplied values. Otherwise, the existing item in the data store is updated with the supplied values, and the lock of the data is released. Only session data for the current application that matches the supplied SessionID and lock identifier values is updated.

After the SetAndReleaseItemExclusive method is called, the ResetItemTimeout method is called by the SessionStateModule to update the expiration date and time of the session-item data.

ReleaseItemExclusive method

Takes as input the HttpContext for the current request, the SessionID for the current request, and the lock identifier for the current request and releases the lock on an item in the session data store. This method is called when the GetItem or GetItemExclusive method is called and the data store specifies that the requested item is locked, but the lock age has exceeded the ExecutionTimeout. The lock is cleared by this method, freeing the item for use by other requests.

RemoveItem method

Takes as input the HttpContext for the current request, the SessionID for the current request, and the lock identifier for the current request and deletes the session information from the data store where the data store item matches the supplied SessionID, the current application, and the supplied lock identifier. This method is called when the Abandon method is called.

CreateUninitializedItem method

Takes as input the HttpContext for the current request, the SessionID for the current request, and the lock identifier for the current request and adds an uninitialized item to the session data store with an actionFlags value of InitializeItem.

The CreateUninitializedItem method is used with Cookieless sessions when the regenerateExpiredSessionId attribute is set to true, which causes the SessionStateModule to generate a new SessionID value when an expired SessionID is encountered.

The process of generating a new SessionID value requires the browser to be redirected to a URL that contains the newly generated SessionID. The CreateUninitializedItem method is called during the initial request that contains an expired SessionID. After the SessionStateModule acquires a new SessionID value to replace the expired SessionID, it calls the CreateUninitializedItem method to add an uninitialized entry to the session-state data store. The browser is then redirected to the URL containing the newly generated SessionID value. The existence of the uninitialized entry in the session data store ensures that the redirected request that includes the newly generated SessionID value is not mistaken for a request for an expired session and is, instead, treated as a new session.

The uninitialized entry in the session data store is associated with the newly generated SessionID and contains only default values, including an expiration date and time, and a value that corresponds to the actionFlags parameter of the GetItem and GetItemExclusive methods. The uninitialized entry in the session state store should include an actionFlags value equal to the InitializeItem enumeration value (1). This value is passed to the SessionStateModule by the GetItem and GetItemExclusive methods and informs the SessionStateModule that the current session is a new session. The SessionStateModule will then initialize the new session and raise the Session_OnStart event.

CreateNewStoreData method

Takes as input the HttpContext for the current request and the Timeout value for the current session and returns a new SessionStateStoreData object with an empty ISessionStateItemCollection object, an HttpStaticObjectsCollection collection, and the specified Timeout value. The HttpStaticObjectsCollection for the ASP.NET application can be retrieved using the GetSessionStaticObjects method.

SetItemExpireCallback method

Takes as input a delegate that references the Session_OnEnd event defined in the Global.asax file. If the session-state store provider supports the Session_OnEnd event, a local reference to the SessionStateItemExpireCallback parameter is set and the method returns true; otherwise, the method returns false.

Sample Provider

To view an example custom session-state store provider implementation that uses the classes in the System.Data.Odbc namespace to manage session information in an Access database, see Sample Session-State Store Provider.

See Also



JavaScript Editor jscript editor     Web designer