在我的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始終是真實的停止請求調用後,但我不知道爲什麼。有誰知道爲什麼會話丟失?在執行停止控制器時是否有錯誤?
好吧,我認爲cookie只是從一個請求中刪除 - 停止請求? – curiosity
「停止」之後,來自同一用戶的以下請求將獲得新會話,但我不知道爲什麼。 – curiosity
@AnnaPrenzel - 你的假設是錯誤的。會話cookie在瀏覽器的所有實例之間共享。如果您刪除了cookie,它將從所有實例中刪除。由於每個Web請求都會發送Cookie,因此當Cookie被移除時,任何新請求(甚至是來自另一個窗口)都不會有Cookie,因此將創建一個新會話。雖然有例外。如果您在「私人」窗口中打開新的窗口,則Cookie與非「私人」窗口分開。 –