0

在我的ASP .NET MVC 2應用程序中,有幾個控制器需要會話狀態。然而,我的一個控制器在某些情況下運行時間很長,客戶端應該能夠阻止它。併發請求:從單個請求中刪除會話ID後會話丟失

這裏是長時間運行的控制器:

[SessionExpireFilter] 
    [NoAsyncTimeout] 
    public void ComputeAsync(...) //needs the session 
    { 
    } 

    public ActionResult ComputeCompleted(...) 
    { 

    } 

這是控制器停止要求:

public ActionResult Stop() 
    { 
     ... 
    } 

不幸的是,在ASP .NET MVC 2個的併發請求是不可能的之一,同一個用戶,所以我的Stop-Request必須等到長時間運行操作完成。因此,我曾嘗試在this article描述的伎倆,並添加了以下處理程序的Global.asax.cs:

protected void Application_BeginRequest() 
    { 
     if (Request.Url.AbsoluteUri.Contains("Stop") && Request.Cookies["ASP.NET_SessionId"] != null) 
     { 
      var session_id = Request.Cookies["ASP.NET_SessionId"].Value; 

      Request.Cookies.Remove("ASP.NET_SessionId"); 
      ... 
     } 
    } 

這僅僅去除停止請求會話ID。乍一看,這種方式運作良好 - 停止請求通過,操作停止。 然而,在那之後,似乎長時間運行請求的用戶的會話已被終止。

我用我自己的SessionExpireFilter以識別會話超時:

public class SessionExpireFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     HttpContext ctx = HttpContext.Current; 

     // check if session is supported 
     if (ctx.Session != null) 
     { 
      // check if a new session id was generated 
      if (ctx.Session.IsNewSession) 
      { 

       // If it says it is a new session, but an existing cookie exists, then it must 
       // have timed out 
       string sessionCookie = ctx.Request.Headers["Cookie"]; 
       if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0)) 
       { 

        filterContext.Result = new JsonResult() { Data = new { success = false, timeout = true }, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; 
       } 
      } 
     } 

     base.OnActionExecuting(filterContext); 
    } 
} 

ctx.Session.IsNewSession始終是真實的停止請求調用後,但我不知道爲什麼。有誰知道爲什麼會話丟失?在執行停止控制器時是否有錯誤?

回答

1

由於您刪除了會話cookie,會話丟失。我不知道爲什麼這似乎不合邏輯。每個新的頁面請求都提供cookie給asp.net,如果沒有cookie,它會生成一個新的cookie。

您可以使用一個選項來使用無Cookie會話,它將向查詢字符串添加一個標記。您只需爲每次登錄或類似操作生成一個新會話。

但這是會話變量不鼓勵的原因之一。您可以更改代碼以使用頁內變量,還是將變量存儲在數據庫中?

+0

好吧,我認爲cookie只是從一個請求中刪除 - 停止請求? – curiosity

+0

「停止」之後,來自同一用戶的以下請求將獲得新會話,但我不知道爲什麼。 – curiosity

+1

@AnnaPrenzel - 你的假設是錯誤的。會話cookie在瀏覽器的所有實例之間共享。如果您刪除了cookie,它將從所有實例中刪除。由於每個Web請求都會發送Cookie,因此當Cookie被移除時,任何新請求(甚至是來自另一個窗口)都不會有Cookie,因此將創建一個新會話。雖然有例外。如果您在「私人」窗口中打開新的窗口,則Cookie與非「私人」窗口分開。 –