151 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			151 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
|  | using System; | ||
|  | using System.Collections; | ||
|  | using System.Diagnostics; | ||
|  | using System.IO; | ||
|  |   | ||
|  | using System.Web; | ||
|  | using System.Web.Caching; | ||
|  | using System.Web.SessionState; | ||
|  | using System.Web.UI; | ||
|  | 
 | ||
|  | namespace view.App_Code | ||
|  | { | ||
|  |     /// <summary> | ||
|  |     /// When an ASP.NET State Server other than InProc, the Session_End event | ||
|  |     /// does not get fired.  This is an HttpModule which uses some workarounds | ||
|  |     /// and fires a static event when a session ends, with the value of a single | ||
|  |     /// configurable session variable in the event arguments. | ||
|  |     /// </summary> | ||
|  |     public class SessionEndModule : IHttpModule | ||
|  |     { | ||
|  |         #region Private Variables | ||
|  | 
 | ||
|  |         private HttpApplication m_HttpApplication; | ||
|  |         private static string m_SessionObjectKey; | ||
|  | 
 | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region Accessors | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// This is the key of the item in the session which should be returned | ||
|  |         /// in the SessionEnd event (as the SessionObject). | ||
|  |         /// </summary> | ||
|  |         /// <example> | ||
|  |         ///	If you're storing the user ID in the session, under a key called 'UserId' | ||
|  |         /// and need to do something with it in the SessionEnd event, you would set | ||
|  |         /// this to 'UserId', which would cause the value of the session key called | ||
|  |         /// 'UserId' to be returned. | ||
|  |         /// </example> | ||
|  |         public static string SessionObjectKey | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return m_SessionObjectKey; | ||
|  |             } | ||
|  |             set | ||
|  |             { | ||
|  |                 m_SessionObjectKey = value; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region IHttpModule Implementation | ||
|  | 
 | ||
|  |         public void Init(HttpApplication context) | ||
|  |         { | ||
|  |             m_HttpApplication = context; | ||
|  |             m_HttpApplication.PreRequestHandlerExecute += new EventHandler(OnPreRequestHandlerExecute); | ||
|  |         } | ||
|  | 
 | ||
|  |         public void Dispose() | ||
|  |         { | ||
|  |             // Do Nothing | ||
|  |         } | ||
|  | 
 | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         #region Events | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// Event raised when the session ends | ||
|  |         /// </summary> | ||
|  |         public static event SessionEndEventHandler SessionEnd; | ||
|  | 
 | ||
|  |         #endregion | ||
|  | 
 | ||
|  |         private void OnPreRequestHandlerExecute(object sender, EventArgs e) | ||
|  |         { | ||
|  |             // We only want to update the session when an ASPX page is being viewed | ||
|  |             // We're also doing this in the PreRequestHandler, as doing it elsewhere | ||
|  |             // (like the PostRequestHandler) can cause some strange behaviour. | ||
|  | 
 | ||
|  |             if (Path.GetExtension(m_HttpApplication.Context.Request.Path).ToLower() == ".aspx") | ||
|  |             { | ||
|  |                 // Ensure we have a HttpContext | ||
|  |                 if (HttpContext.Current == null) | ||
|  |                 { | ||
|  |                     Debug.WriteLine("No current http context"); | ||
|  |                     return; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 // Get the current session | ||
|  |                 HttpSessionState currentSession = HttpContext.Current.Session; | ||
|  | 
 | ||
|  |                 // Ensure we have a current session | ||
|  |                 if (currentSession == null) | ||
|  |                 { | ||
|  |                     Debug.WriteLine("No current session"); | ||
|  |                     return; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 // Get the session timeout | ||
|  |                 TimeSpan sessionTimeout = new TimeSpan(0, 0, currentSession.Timeout, 0, 0); | ||
|  | 
 | ||
|  |                 // Get the object in the session we want to retrieve when the session times out | ||
|  |                 object sessionObject = currentSession[SessionObjectKey]; | ||
|  | 
 | ||
|  |                 // Add the object to the cache with the current session id, and set a cache removal callback method | ||
|  |                 HttpContext.Current.Cache.Insert(currentSession.SessionID, sessionObject, null, DateTime.MaxValue, sessionTimeout, CacheItemPriority.NotRemovable, CacheItemRemovedCallbackMethod); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         /// <summary> | ||
|  |         /// This method is fired when an item is removed from the cache.  It is used to detect when a cache item | ||
|  |         /// expires, indicating that the session has expired, and fires the SessionEnd event. | ||
|  |         /// </summary> | ||
|  |         private void CacheItemRemovedCallbackMethod(string key, object value, CacheItemRemovedReason reason) | ||
|  |         { | ||
|  |             if (reason == CacheItemRemovedReason.Expired) | ||
|  |             { | ||
|  |                 if (SessionEnd != null) | ||
|  |                 { | ||
|  |                      SessionEndedEventArgs e = new SessionEndedEventArgs(key, value); | ||
|  |                      SessionEnd(this, e); | ||
|  |                       | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /// <summary> | ||
|  |     /// Event handler for handling the SessionEnd event | ||
|  |     /// </summary> | ||
|  |     public delegate void SessionEndEventHandler(object sender, SessionEndedEventArgs e); | ||
|  | 
 | ||
|  |     /// <summary> | ||
|  |     /// SessionEndedEventArgs for use in the SessionEnd event | ||
|  |     /// </summary> | ||
|  |     public class SessionEndedEventArgs : EventArgs | ||
|  |     { | ||
|  |         public readonly string SessionId; | ||
|  |         public readonly object SessionObject; | ||
|  | 
 | ||
|  |         public SessionEndedEventArgs(string sessionId, object sessionObject) | ||
|  |         {    | ||
|  |             SessionId = sessionId; | ||
|  |             SessionObject = sessionObject; | ||
|  |         } | ||
|  |     } | ||
|  | } |