在我的 ASP .NET MVC 2 - 应用程序中,有几个控制器需要会话状态。但是,在某些情况下,我的控制器之一运行时间很长,客户端应该能够停止它。
这是长时间运行的控制器:
[SessionExpireFilter]
[NoAsyncTimeout]
public void ComputeAsync(...) //needs the session
{
}
public ActionResult ComputeCompleted(...)
{
}
这是停止请求的控制器:
public ActionResult Stop()
{
...
}
不幸的是,在 ASP .NET MVC 2 中,同一用户不可能同时请求,因此我的 Stop-Request 必须等到长时间运行的操作完成。因此,我尝试了本文中描述的技巧,并将以下处理程序添加到 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);
}
}
调用 Stop-Request 后 ctx.Session.IsNewSession 始终为真,但我不知道为什么。有谁知道为什么会话丢失?Stop-Controller的实现是否有任何错误?