SessionStateUtility 类

定义

提供会话状态模块和会话状态存储提供程序使用的 Helper 方法,为 ASP.NET 应用程序管理会话信息。 此类不能被继承。

public static class SessionStateUtility
继承
SessionStateUtility

示例

下面的代码示例演示了一个自定义会话状态模块实现,该实现使用 Hashtable将会话信息存储在内存中。 该模块使用 SessionStateUtility 类引用当前 HttpContextSessionIDManager,检索当前 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);
        }
    }
}

若要在 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)

从指定上下文中移除会话数据。

适用于

产品 版本
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1

另请参阅