【问题标题】:Concurrent requests: session lost after removing session-id from one single request并发请求:从单个请求中删除会话 ID 后会话丢失
【发布时间】:2012-10-11 17:52:48
【问题描述】:

在我的 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");
            ...
        }
    }

这只是从停止请求中删除会话 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的实现是否有错误?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 好的,我假设 cookie 仅从一个请求中删除 - 停止请求?
    • 在“停止”之后,来自同一用户的以下请求获得了新会话,但我不知道为什么。
    • @AnnaPrenzel - 你的假设是错误的。会话 cookie 在浏览器的所有实例之间共享。如果您删除 cookie,它将从所有实例中删除。由于每个 Web 请求都会发送 cookie,当 cookie 被删除时,任何新请求(即使来自另一个窗口)都不会有 cookie,因此将创建一个新会话。不过也有例外。如果您打开一个新的“私人”窗口,则 cookie 与非“私人”窗口是分开的。
    猜你喜欢
    • 1970-01-01
    • 2018-01-04
    • 2011-06-14
    • 2015-02-23
    • 2018-04-15
    • 2015-08-20
    • 2011-07-12
    • 2014-11-06
    • 2012-11-28
    相关资源
    最近更新 更多