并发请求:从一个请求中删除session-id后会话丢失

时间:2012-10-11 17:52:49

标签: asp.net-mvc session web-applications asp.net-mvc-2 session-timeout

在我的ASP .NET MVC 2 - 应用程序中,有几个需要会话状态的控制器。但是,在某些情况下,我的某个控制器运行时间很长,客户端应该可以停止它。

这是长时间运行的控制器:

    [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");
            ...
        }
    }

这只是从Stop-Request中删除了session-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始终为true,但我不知道原因。有谁知道会话丢失的原因?停止控制器的实现是否有任何错误?

1 个答案:

答案 0 :(得分:1)

由于您删除了会话Cookie,因此会话丢失。我不确定为什么这看起来不合逻辑。每个新的页面请求都将cookie提供给asp.net,如果没有cookie,它会生成一个新的。

您可以使用一个选项来使用无cookie会话,这将为查询字符串添加一个令牌。您需要做的就是为每次登录生成一个新会话,或类似的。

但这是不鼓励会话变量的原因之一。您可以更改代码以使用页内变量,还是将变量存储在数据库中?