SessionStateUtility 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
提供工作階段狀態模組和工作階段狀態存放區提供者所使用的 Helper 方法,以管理 ASP.NET 應用程式的工作階段資訊。 此類別無法獲得繼承。
public ref class SessionStateUtility abstract sealed
public static class SessionStateUtility
type SessionStateUtility = class
Public Class SessionStateUtility
- 繼承
-
SessionStateUtility
範例
下列程式代碼範例示範使用 將會話資訊儲存在記憶體 Hashtable中的自定義會話狀態模組實作。 模組會SessionStateUtility使用 類別來參考目前的 和 SessionIDManager,擷取目前的 HttpContextHttpStaticObjectsCollection,並引發 ASP.NET 應用程式之 Global.asax 檔案中定義的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的會話數據中。 |
會話數據會以 物件或介面的任何有效實作IHttpSessionState的形式傳遞至目前 並從中HttpContextHttpSessionStateContainer擷取。
如需實作會話狀態存放區提供者的相關信息,請參閱 實作 Session-State 存放區提供者。
屬性
SerializationSurrogateSelector |
取得或設定會用於工作階段序列化自訂的序列化 Surrogate 選取器。 |
方法
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) |
從指定的內容中移除工作階段資料。 |