如何判斷一個SessionId是否已Timeout?

  • 10701
  • 0

如何判斷一個SessionId是否已Timeout?

前言

有同事問,要如何判斷一個SessionId是否已Timeout呢? 直覺想就是在global.asax的Session_Start & Session_End裡面去動手腳,加入一個Hashtable去記錄。但是,如果把Session是放在StateServer或是SQL Server的話,那就不會引發Session_End事件。

 

研究

在CodeProject中找到了「ASP.NET HttpModule for handling session end with StateServer」一篇文章,它是寫一個HttpModule,再使用Cache的Timeout來模擬Session的Timeout。當Cache Timeout時,再引發自定的SessionEnd事件。

 

實作

因為自定的SessionEnd事件是Static Event,所以無法使用HttpContext.Current取到Application物件,所以就在SessionEndedEventArgs裡加入HttpApplicationState物件以方便在SessionEnd時,可以存取到Application。

Session1

vsdebug

要達到檢查某個SessionId是否Timeout,我們要先用個Hashtable去記錄。

  • 在Application_Start事件中建立Hashtable。
{
    Debug.WriteLine("Application started");
    SessionEndModule.SessionObjectKey = "UserEmail";
    SessionEndModule.SessionEnd += new SessionEndEventHandler(SessionTimoutModule_SessionEnd);
    //建立放SessionID的Hashtable
    Hashtable htSession = new Hashtable();
    Application["SessionList"] = htSession;
}
  • 在Session_Start事件中把SessionId加到Hashtable之中。
{
    Debug.WriteLine("Session started: " + Session.SessionID);
    Session["UserId"] = new Random().Next(1, 100);
    Session["UserEmail"] = new Random().Next(100, 1000).ToString() + "@domain.com";
    //加入到SessionList
    ((Hashtable)Application["SessionList"]).Add(Session.SessionID, Session["UserId"]);
}
  • 在自定的SessionEnd事件中,把SessionId從Hashtable之中移除。
{
    Debug.WriteLine("SessionTimoutModule_SessionEnd : SessionId : " + e.SessionId);

    // This will be the value in the session for the key specified in Application_Start
    object sessionObject = e.SessionObject;

    string val = (sessionObject == null) ? "[null]" : sessionObject.ToString();
    Debug.WriteLine("Returned value: " + val);
    //移除SessionList
    ((Hashtable)e.HttpApp["SessionList"]).Remove(e.SessionId);
}
  • 要檢查SessionId是否有Timeout,只要Check Hashtable之中是否有該SessionId即可!
{
    string sid = txtSessionID.Text.Trim();
    if (((Hashtable)Application["SessionList"]).ContainsKey(sid))
        lblMsg.Text = "SessionID:" + sid + " Session還沒TimeOut!";
    else
        lblMsg.Text = "SessionID:" + sid + " Session已經TimeOut!";
}

 

  • Web.config中sessionState設定為StateServer,timeout設定為1分鐘。另外,記得ASP.NET State Service啟動哦!

<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="1" cookieless="false"/>

 

附上測試程式碼:

SessionTimeOut.rar

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^