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;
|
||
|
}
|
||
|
}
|
||
|
}
|