SessionStateModule类
为一个应用程序提供session-state服务.这个类不能继承.
[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] public sealed class SessionStateModule : IHttpModule
SessionStateModle 是ASP.NET的默认Sssion-state Handler,它写入session 数据并且从session-state存储中找回它和调用Session_OnStart和Session_OnEnd事件.下面详细关于怎样使用ASP.NET session state 去存储和为一个用户session找回值. 你能自定义实现IHttpModule接口取代SessionStateModule. (1)IHttpModule Interface
提供module初始化和配置事件去实现类.
[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)][AspNetHostingPermissionAttribute(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public interface IHttpModule
(2)SessionStateUtility Class
提供由session-state modules和session-state储存提供者提供去管理ASP.NET应用程序Session信息helper方法.
[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] public static class SessionStateUtility
注意 SessionStateUtility类提供static helper方法,这个方法被一个session-state module所使用或一个session-state存储提供者.应用程序开发者不需要使用他们的代码调用这些方法. 下面是session-state module和session-state 储存者使用的方法: (3)SessionStateUtility.GetHttpSessionStateFromContext Method
从当前请求context中找回session data.
public static IHttpSessionState GetHttpSessionStateFromContext( HttpContext context)
Context参数为HttpContext 返回值类型为System.Web.SessionState.IHttpSessionState. 从当前请求中的Session 数据迁移到IHttpSessionState实现实例. GetHttpSessionStateFromContext 方法能被一个session-state module使用来从当前请求中找回session data.在触发RelesseRequestState期间是在在一个请求结束时.返回session数据,之后被写入session数据存储.如果Session已经被废弃,这个session数据能从数据存储中被移出和HttpContext,并且Session_OnEnd时间就被执行. 注意: 你能使用RemoveHttpSessionStateFromContext方法去移出session 数据,并且使用 RaiseSessionEnd调用Session_OnEnd事件. 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);}
(4)SessionStateUtility.AddHttpSessionStateToContext Method
从当前请求context里申请session数据.
public static void AddHttpSessionStateToContext( HttpContext context, IHttpSessionState container)
参数: context:就是HttpContext. container:类型为IHttpSessionState,实现这个实例添加进去详细的HTTP context. 注意: AddHttpSessionStateToContext方法被一个session-state module用来在当前请求中添加session 数据,在开始请求触发AcquireRequestState事件期间.在当前请求Session数据既会找回现有session或创建一个新的session.这个Session数据是封装在一个IHttpSesssionState实现的实例中.与当前的HttpContext一起传给AddHttpSessionStateToContext方法中.提供Session数据之后通过当前context的Session属性产生可是使用的应用程序代码. (5)SessionStateUtility.RemoveHttpSessionStateFromContext方法
从context中移出session data.
public static void RemoveHttpSessionStateFromContext( HttpContext context)
参数: cotext:就是HttpContext; 注意: RemoveHttpSessionStateFromContext 方法是从HttpContext中清出session数据.一个 session-state module将在ReleaseRequestState事件handler中调用RemoveHttpSessionStateFromContext. (6)SessionStateUtility.GetSessionStaticObjects Method
从context中得到一个static Object collection引用. 参数: context:类型为HttpContext. GetSessionStaticObjects被使用来找回定义在Global.asax文件中的static object collection.一个session-state module实现将提供返回HttpStaticObjcetCollection 集合去在IHttpSessionState实现的实例中使用AddHttpSessionStateToContext方法添加进当前context.
(7)HttpSessionStateContainer 类
包括Session-state值也有为当前去请求session-level设置. Session data 传递和从当前的HttpContext中找回,就如HttpSessionStateContainer对象或任何有效的IHttpSessionState接口的实现都可以做到. ASP.NET提供session-state管理允许你存储信息结合一个唯一浏览器session跨越多个请求.你能存储在用key,index控制的一个值的collection中.访问Session值并且结合通过当前请求的Sesion属性或Page的Session属性给HttpSessionState类所使用,而这个HttpSessionState类访问Sesion-state值和session-level设置都在一个Sesion-state Container设置和引用,而这个HttpSessionState interface的实现已经迁移session-state数据并且由session-state module为HttpApplication添加进当前请求的HttpContext中. 而这个HttpSessionState类调用HttpSessionStateContainer类,来管理在内存中的session的设置和值. 在HttpSessionStateContainer类是HttpSessionState interface的ASP.NET实现.这个HttpSessionStateContainer类不需要调用应用程序代码.如果你要使用custom Session-state module替换SessionStateModule,你能使用HttpSessionStateContainer class或提供你自己的IHttpSessionState interface的实现.
当创建一个SessionStateStoreData时对象一个sessionStateStoreProviderBase还能使用GetSessionStaticObjcets方法. 下面代码为一custom session-state module实现使用Hashtable存储session信息.这个module使用SessionStateUtility 类去引用当前请求的HttpContext和SessionIDManager,重新找回当前的HttpStaticObjcetCollection,并且调用Session_OnEnd事件定义在Global.asax文件.但这里没有防止多个Web请求使用相同的session 标记.
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); } }}
还有下面的 configuration