2013-10-12 144 views
7

我有一個使用Windows Authentication的MVC4應用程序。用戶可以鍵入任意10個視圖的url來加載應用程序。沒有具體的主頁會話超時處理的會話啓動和操作過濾器

如果用戶閒置超過一分鐘,我需要重定向到會話超時視圖。我將會話超時值保存在配置文件中爲一分鐘。我創建了一個action filter來檢查一個特定的會話值。此特定會話值在Global.asaxSession_Start中設置。

但是,當超時時間結束時,請求再次遇到Session_Start並且它正在分配值。因此我的動作過濾器不會重定向到錯誤視圖。 有什麼可以解決這個問題的解決方案?

的Web.Config

<system.web> 
    <!--Impersonate--> 
    <identity impersonate="true"/> 
     <!--Session Mode and Timeout--> 
    <sessionState mode="InProc" timeout="1" /> 
    <authentication mode="Windows"> 
    </authentication> 
    <authorization> 
     <allow users="?" /> 
    </authorization>  
</system.web> 

行爲過濾

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
public class SessionCheckAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext) 
    { 
     string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower(); 
     HttpSessionStateBase session = filterContext.HttpContext.Session; 
     var activeSession = session["IsActiveSession"]; 
     if (activeSession == null) 
     { 
      //Redirect 
      var url = new UrlHelper(filterContext.RequestContext); 
      var loginUrl = url.Content("~/Error/SessionTimeout"); 
      filterContext.HttpContext.Response.Redirect(loginUrl, true); 
     } 
    } 
} 

的Global.asax

protected void Session_Start(object sender, EventArgs e) 
{ 
    Session["IsActiveSession"] = DateTime.Now; 
} 
+0

參考:http://stackoverflow.com/questions/199099/how-to-manage-a-redirect-request-after-a-jquery-ajax-call – Lijo

+0

和http://stackoverflow.com/questions/ 16259230/worldwide-filter-ajax-success-handlers和[408錯誤代碼](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) – Lijo

回答

10

而不是設置會話值並在您的操作篩選器中檢查它,只需檢查HttpContext.Current.Session.IsNewSession以查看是否爲當前請求創建了新會話。修改您的行爲過濾器,你最終會得到這樣的:

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
public class SessionCheckAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext) 
    { 
     string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower(); 
     HttpSessionStateBase session = filterContext.HttpContext.Session; 
     if (session.IsNewSession) 
     { 
      //Redirect 
      var url = new UrlHelper(filterContext.RequestContext); 
      var loginUrl = url.Content("~/Error/SessionTimeout"); 
      filterContext.HttpContext.Response.Redirect(loginUrl, true); 
     } 

    } 
} 

,如果你想獲得幻想,並確保他們有是爲這個請求創建新的會話之前的先前會話,你可以更新檢查if聲明,如果一個老的會話cookie與請求一起發送:

string cookieHeader = filterContext.HttpContext.Request.Headers["Cookie"]; 
if (session.IsNewSession && cookieHeader != null && cookieHeader.IndexOf("ASP.NET_SessionId") >= 0) 
{ 
    ... 
} 

但是,因爲它看起來像你將它們發送到登錄頁面,這可能不是你約人擔心的東西。如果您確實使用此檢查,請注意此代碼採用默認的"ASP.NET_SessionId" Cookie名稱;這可以在web.config中更改,在這種情況下,您需要使用新的cookie名稱或get the cookie name programmatically來更新IndexOf參數。

+1

博客文章鏈接已損壞。 – RickNZ

+2

謝謝,我已將其替換。 – markegli

+1

解釋如何檢查舊會話的鏈接並不理想,因此我剛剛將內聯解釋移開。 – markegli