SessionStateUtility 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
提供会话状态模块和会话状态存储提供程序使用的 Helper 方法,为 ASP.NET 应用程序管理会话信息。 此类不能被继承。
public ref class SessionStateUtility abstract sealed
public static class SessionStateUtility
type SessionStateUtility = class
Public Class SessionStateUtility
- 继承
-
SessionStateUtility
示例
下面的代码示例演示了一个自定义会话状态模块实现,该实现使用 Hashtable将会话信息存储在内存中。 该模块使用 SessionStateUtility 类引用当前 HttpContext 和 SessionIDManager,检索当前 HttpStaticObjectsCollection,并引发在 Global.asax 文件中为 ASP.NET 应用程序定义的 Session_OnEnd 事件。 此应用程序不会阻止同时 Web 请求使用相同的会话标识符。
using System;
using System.Web;
using System.Web.SessionState;
using System.Collections;
using System.Threading;
using System.Web.Configuration;
using System.Configuration;
namespace Samples.AspNet.SessionState
{
public sealed class MySessionStateModule : IHttpModule, IDisposable
{
private Hashtable pSessionItems = new Hashtable();
private Timer pTimer;
private int pTimerSeconds = 10;
private bool pInitialized = false;
private int pTimeout;
private HttpCookieMode pCookieMode = HttpCookieMode.UseCookies;
private ReaderWriterLock pHashtableLock = new ReaderWriterLock();
private ISessionIDManager pSessionIDManager;
private SessionStateSection pConfig;
// The SessionItem class is used to store data for a particular session along with
// an expiration date and time. SessionItem objects are added to the local Hashtable
// in the OnReleaseRequestState event handler and retrieved from the local Hashtable
// in the OnAcquireRequestState event handler. The ExpireCallback method is called
// periodically by the local Timer to check for all expired SessionItem objects in the
// local Hashtable and remove them.
private class SessionItem
{
internal SessionStateItemCollection Items;
internal HttpStaticObjectsCollection StaticObjects;
internal DateTime Expires;
}
//
// IHttpModule.Init
//
public void Init(HttpApplication app)
{
// Add event handlers.
app.AcquireRequestState += new EventHandler(this.OnAcquireRequestState);
app.ReleaseRequestState += new EventHandler(this.OnReleaseRequestState);
// Create a SessionIDManager.
pSessionIDManager = new SessionIDManager();
pSessionIDManager.Initialize();
// If not already initialized, initialize timer and configuration.
if (!pInitialized)
{
lock (typeof(MySessionStateModule))
{
if (!pInitialized)
{
// Create a Timer to invoke the ExpireCallback method based on
// the pTimerSeconds value (e.g. every 10 seconds).
pTimer = new Timer(new TimerCallback(this.ExpireCallback),
null,
0,
pTimerSeconds * 1000);
// Get the configuration section and set timeout and CookieMode values.
Configuration cfg =
WebConfigurationManager.OpenWebConfiguration(System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);
pConfig = (SessionStateSection)cfg.GetSection("system.web/sessionState");
pTimeout = (int)pConfig.Timeout.TotalMinutes;
pCookieMode = pConfig.Cookieless;
pInitialized = true;
}
}
}
}
//
// IHttpModule.Dispose
//
public void Dispose()
{
if (pTimer != null)
{
this.pTimer.Dispose();
((IDisposable)pTimer).Dispose();
}
}
//
// Called periodically by the Timer created in the Init method to check for
// expired sessions and remove expired data.
//
void ExpireCallback(object state)
{
try
{
pHashtableLock.AcquireWriterLock(Int32.MaxValue);
this.RemoveExpiredSessionData();
}
finally
{
pHashtableLock.ReleaseWriterLock();
}
}
//
// Recursivly remove expired session data from session collection.
//
private void RemoveExpiredSessionData()
{
string sessionID;
foreach (DictionaryEntry entry in pSessionItems)
{
SessionItem item = (SessionItem)entry.Value;
if ( DateTime.Compare(item.Expires, DateTime.Now)<=0 )
{
sessionID = entry.Key.ToString();
pSessionItems.Remove(entry.Key);
HttpSessionStateContainer stateProvider =
new HttpSessionStateContainer(sessionID,
item.Items,
item.StaticObjects,
pTimeout,
false,
pCookieMode,
SessionStateMode.Custom,
false);
SessionStateUtility.RaiseSessionEnd(stateProvider, this, EventArgs.Empty);
this.RemoveExpiredSessionData();
break;
}
}
}
//
// Event handler for HttpApplication.AcquireRequestState
//
private void OnAcquireRequestState(object source, EventArgs args)
{
HttpApplication app = (HttpApplication)source;
HttpContext context = app.Context;
bool isNew = false;
string sessionID;
SessionItem sessionData = null;
bool supportSessionIDReissue = true;
pSessionIDManager.InitializeRequest(context, false, out supportSessionIDReissue);
sessionID = pSessionIDManager.GetSessionID(context);
if (sessionID != null)
{
try
{
pHashtableLock.AcquireReaderLock(Int32.MaxValue);
sessionData = (SessionItem)pSessionItems[sessionID];
if (sessionData != null)
sessionData.Expires = DateTime.Now.AddMinutes(pTimeout);
}
finally
{
pHashtableLock.ReleaseReaderLock();
}
}
else
{
bool redirected, cookieAdded;
sessionID = pSessionIDManager.CreateSessionID(context);
pSessionIDManager.SaveSessionID(context, sessionID, out redirected, out cookieAdded);
if (redirected)
return;
}
if (sessionData == null)
{
// Identify the session as a new session state instance. Create a new SessionItem
// and add it to the local Hashtable.
isNew = true;
sessionData = new SessionItem();
sessionData.Items = new SessionStateItemCollection();
sessionData.StaticObjects = SessionStateUtility.GetSessionStaticObjects(context);
sessionData.Expires = DateTime.Now.AddMinutes(pTimeout);
try
{
pHashtableLock.AcquireWriterLock(Int32.MaxValue);
pSessionItems[sessionID] = sessionData;
}
finally
{
pHashtableLock.ReleaseWriterLock();
}
}
// Add the session data to the current HttpContext.
SessionStateUtility.AddHttpSessionStateToContext(context,
new HttpSessionStateContainer(sessionID,
sessionData.Items,
sessionData.StaticObjects,
pTimeout,
isNew,
pCookieMode,
SessionStateMode.Custom,
false));
// Execute the Session_OnStart event for a new session.
if (isNew && Start != null)
{
Start(this, EventArgs.Empty);
}
}
//
// Event for Session_OnStart event in the Global.asax file.
//
public event EventHandler Start;
//
// Event handler for HttpApplication.ReleaseRequestState
//
private void OnReleaseRequestState(object source, EventArgs args)
{
HttpApplication app = (HttpApplication)source;
HttpContext context = app.Context;
string sessionID;
// Read the session state from the context
HttpSessionStateContainer stateProvider =
(HttpSessionStateContainer)(SessionStateUtility.GetHttpSessionStateFromContext(context));
// If Session.Abandon() was called, remove the session data from the local Hashtable
// and execute the Session_OnEnd event from the Global.asax file.
if (stateProvider.IsAbandoned)
{
try
{
pHashtableLock.AcquireWriterLock(Int32.MaxValue);
sessionID = pSessionIDManager.GetSessionID(context);
pSessionItems.Remove(sessionID);
}
finally
{
pHashtableLock.ReleaseWriterLock();
}
SessionStateUtility.RaiseSessionEnd(stateProvider, this, EventArgs.Empty);
}
SessionStateUtility.RemoveHttpSessionStateFromContext(context);
}
}
}
Imports System.Web
Imports System.Web.SessionState
Imports System.Collections
Imports System.Threading
Imports System.Web.Configuration
Imports System.Configuration
Namespace Samples.AspNet.SessionState
Public NotInheritable Class MySessionStateModule
Implements IHttpModule, IDisposable
Private pSessionItems As Hashtable = New Hashtable()
Private pTimer As Timer
Private pTimerSeconds As Integer = 10
Private pInitialized As Boolean = False
Private pTimeout As Integer
Private pCookieMode As HttpCookieMode = HttpCookieMode.UseCookies
Private pHashtableLock As ReaderWriterLock = New ReaderWriterLock()
Private pSessionIDManager As ISessionIDManager
Private pConfig As SessionStateSection
' The SessionItem class is used to store data for a particular session along with
' an expiration date and time. SessionItem objects are added to the local Hashtable
' in the OnReleaseRequestState event handler and retrieved from the local Hashtable
' in the OnAcquireRequestState event handler. The ExpireCallback method is called
' periodically by the local Timer to check for all expired SessionItem objects in the
' local Hashtable and remove them.
Private Class SessionItem
Friend Items As SessionStateItemCollection
Friend StaticObjects As HttpStaticObjectsCollection
Friend Expires As DateTime
End Class
'
' IHttpModule.Init
'
Public Sub Init(ByVal app As HttpApplication) Implements IHttpModule.Init
' Add event handlers.
AddHandler app.AcquireRequestState, New EventHandler(AddressOf Me.OnAcquireRequestState)
AddHandler app.ReleaseRequestState, New EventHandler(AddressOf Me.OnReleaseRequestState)
' Create a SessionIDManager.
pSessionIDManager = New SessionIDManager()
pSessionIDManager.Initialize()
' If not already initialized, initialize timer and configuration.
If Not pInitialized Then
SyncLock GetType(MySessionStateModule)
If Not pInitialized Then
' Create a Timer to invoke the ExpireCallback method based on
' the pTimerSeconds value (e.g. every 10 seconds).
pTimer = New Timer(New TimerCallback(AddressOf Me.ExpireCallback), _
Nothing, _
0, _
pTimerSeconds * 1000)
' Get the configuration section and set timeout and CookieMode values.
Dim cfg As System.Configuration.Configuration = _
WebConfigurationManager.OpenWebConfiguration( _
System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath)
pConfig = CType(cfg.GetSection("system.web/sessionState"), SessionStateSection)
pTimeout = CInt(pConfig.Timeout.TotalMinutes)
pCookieMode = pConfig.Cookieless
pInitialized = True
End If
End SyncLock
End If
End Sub
'
' IHttpModule.Dispose
'
Public Sub Dispose() Implements IHttpModule.Dispose, IDisposable.Dispose
If Not pTimer Is Nothing Then CType(pTimer, IDisposable).Dispose()
End Sub
'
' Called periodically by the Timer created in the Init method to check for
' expired sessions and remove expired data.
'
Sub ExpireCallback(ByVal state As Object)
Try
pHashtableLock.AcquireWriterLock(Int32.MaxValue)
Me.RemoveExpiredSessionData()
Finally
pHashtableLock.ReleaseWriterLock()
End Try
End Sub
'
' Recursivly remove expired session data from session collection.
'
Private Sub RemoveExpiredSessionData()
Dim sessionID As String
Dim entry As DictionaryEntry
For Each entry In pSessionItems
Dim item As SessionItem = CType(entry.Value, SessionItem)
If DateTime.Compare(item.Expires, DateTime.Now) <= 0 Then
sessionID = entry.Key.ToString()
pSessionItems.Remove(entry.Key)
Dim stateProvider As HttpSessionStateContainer = _
New HttpSessionStateContainer(sessionID, _
item.Items, _
item.StaticObjects, _
pTimeout, _
False, _
pCookieMode, _
SessionStateMode.Custom, _
False)
SessionStateUtility.RaiseSessionEnd(stateProvider, Me, EventArgs.Empty)
Me.RemoveExpiredSessionData()
Exit For
End If
Next entry
End Sub
'
' Event handler for HttpApplication.AcquireRequestState
'
Private Sub OnAcquireRequestState(ByVal [source] As Object, ByVal args As EventArgs)
Dim app As HttpApplication = CType([source], HttpApplication)
Dim context As HttpContext = app.Context
Dim isNew As Boolean = False
Dim sessionID As String
Dim sessionData As SessionItem = Nothing
Dim supportSessionIDReissue As Boolean = True
pSessionIDManager.InitializeRequest(context, False, supportSessionIDReissue)
sessionID = pSessionIDManager.GetSessionID(context)
If Not (sessionID Is Nothing) Then
Try
pHashtableLock.AcquireReaderLock(Int32.MaxValue)
sessionData = CType(pSessionItems(sessionID), SessionItem)
If Not (sessionData Is Nothing) Then
sessionData.Expires = DateTime.Now.AddMinutes(pTimeout)
End If
Finally
pHashtableLock.ReleaseReaderLock()
End Try
Else
Dim redirected, cookieAdded As Boolean
sessionID = pSessionIDManager.CreateSessionID(context)
pSessionIDManager.SaveSessionID(context, sessionID, redirected, cookieAdded)
If redirected Then Return
End If
If sessionData Is Nothing Then
' Identify the session as a new session state instance. Create a new SessionItem
' and add it to the local Hashtable.
isNew = True
sessionData = New SessionItem()
sessionData.Items = New SessionStateItemCollection()
sessionData.StaticObjects = SessionStateUtility.GetSessionStaticObjects(context)
sessionData.Expires = DateTime.Now.AddMinutes(pTimeout)
Try
pHashtableLock.AcquireWriterLock(Int32.MaxValue)
pSessionItems(sessionID) = sessionData
Finally
pHashtableLock.ReleaseWriterLock()
End Try
End If
' Add the session data to the current HttpContext.
SessionStateUtility.AddHttpSessionStateToContext(context, _
New HttpSessionStateContainer(sessionID, _
sessionData.Items, _
sessionData.StaticObjects, _
pTimeout, _
isNew, _
pCookieMode, _
SessionStateMode.Custom, _
False))
' Execute the Session_OnStart event for a new session.
If isNew Then RaiseEvent Start(Me, EventArgs.Empty)
End Sub
'
' Event for Session_OnStart event in the Global.asax file.
'
Public Event Start As EventHandler
'
' Event handler for HttpApplication.ReleaseRequestState
'
Private Sub OnReleaseRequestState(ByVal [source] As Object, ByVal args As EventArgs)
Dim app As HttpApplication = CType([source], HttpApplication)
Dim context As HttpContext = app.Context
Dim sessionID As String
' Read the session state from the context
Dim stateProvider As HttpSessionStateContainer = _
CType(SessionStateUtility.GetHttpSessionStateFromContext(context), HttpSessionStateContainer)
' If Session.Abandon() was called, remove the session data from the local Hashtable
' and execute the Session_OnEnd event from the Global.asax file.
If stateProvider.IsAbandoned Then
Try
pHashtableLock.AcquireWriterLock(Int32.MaxValue)
sessionID = pSessionIDManager.GetSessionID(context)
pSessionItems.Remove(sessionID)
Finally
pHashtableLock.ReleaseWriterLock()
End Try
SessionStateUtility.RaiseSessionEnd(stateProvider, Me, EventArgs.Empty)
End If
SessionStateUtility.RemoveHttpSessionStateFromContext(context)
End Sub
End Class
End Namespace
若要在 ASP.NET 应用程序中使用此自定义会话状态模块,可以替换 Web.config 文件中的现有 SessionStateModule 引用,如以下示例所示。
<configuration>
<system.web>
<httpModules>
<remove name="Session" />
<add name="Session"
type="Samples.AspNet.SessionState.MySessionStateModule" />
</httpModules>
</system.web>
</configuration>
注解
类 SessionStateUtility 提供会话状态模块或会话状态存储提供程序使用的静态帮助程序方法。 应用程序开发人员无需从其代码调用这些方法。
下表介绍了会话状态模块和会话状态存储提供程序使用方法的方式。
方法 | 使用 |
---|---|
GetHttpSessionStateFromContext 方法 | 自定义会话状态模块可用于检索现有会话的会话信息或为新会话创建会话信息。 |
AddHttpSessionStateToContext 方法 | 由会话状态模块调用,以将会话数据添加到当前 HttpContext ,并通过 属性将其提供给应用程序代码 Session 。 |
RemoveHttpSessionStateFromContext 方法 | 在请求结束时由 或 EndRequest 事件期间ReleaseRequestState由会话状态模块调用,以从当前 HttpContext清除会话数据。 |
GetSessionStaticObjects 方法 | 由会话状态模块调用,以基于 Global.asax 文件中定义的对象获取对集合的引用 StaticObjects 。 返回 HttpStaticObjectsCollection 的集合包含在添加到当前 HttpContext的会话数据中。 |
会话数据作为 HttpSessionStateContainer 对象或接口的任何有效实现传递到当前 HttpContext 并从中IHttpSessionState检索。
有关实现会话状态存储提供程序的信息,请参阅 实现 Session-State 存储提供程序。
属性
SerializationSurrogateSelector |
获取或设置用于会话串行自定义的的串行代理选择器。 |
方法
AddHttpSessionStateToContext(HttpContext, IHttpSessionState) |
把会话数据应用到当前请求的上下文。 |
GetHttpSessionStateFromContext(HttpContext) |
从当前请求的上下文检索会话数据。 |
GetSessionStaticObjects(HttpContext) |
引用指定上下文的静态对象集合。 |
IsSessionStateReadOnly(HttpContext) |
获取一个值,该值指示对于指定 HttpContext 的会话状态是否为只读。 |
IsSessionStateRequired(HttpContext) |
获取一个值,该值指示指定的 HttpContext 是否需要会话状态。 |
RaiseSessionEnd(IHttpSessionState, Object, EventArgs) |
为 ASP.NET 应用程序执行 Global.asax 文件中定义的 Session_OnEnd 事件。 |
RemoveHttpSessionStateFromContext(HttpContext) |
从指定上下文中移除会话数据。 |