代码之家  ›  专栏  ›  技术社区  ›  mike nelson

导致_会话状态的原因已创建会话ID,但无法保存它,因为响应已被应用程序刷新。

  •  68
  • mike nelson  · 技术社区  · 16 年前

    我间歇性地犯这个错误。

    我找到了这个链接,它很好地总结了我在谷歌上所能找到的东西: http://www.wacdesigns.com/2009/02/03/session-state-has-created-a-session-id-but-cannot-save-it-because-the-response-was-already-flushed-by-the-application/

    基本上,它说您可以尝试设置web配置设置displaywhennewsession,或者尝试通过在会话开始时获取session.sessionid来将会话状态事件激活。

    但是否有人:

    a)对此有一个解释

    或者更好,b)尝试并测试了修复

    我意识到在做任何会影响HTTP响应头的事情之后,我都无法刷新响应。如果我这样做会导致一个错误 每一次 但这是间歇性的。sessionid肯定应该由ASP.NET在页面响应开始时自动创建,在ASPX页面或页面加载(调用所有刷新的地方)中的任何内容之前。

    更新: 经过深思熟虑,我意识到这是在将文件流式传输到浏览器时发生的。大多数浏览器实际上是搜索引擎机器人。我可以通过启动下载然后关闭浏览器来重新创建此错误,因此在取消下载操作之前,浏览器可能没有等待下载完成。我也在其他普通页面上看到过,但99%的时间是下载页面。

    5 回复  |  直到 8 年前
        1
  •  73
  •   eitama    15 年前

    我有!

    在global.asax文件中,执行以下操作:

    void Session_Start(object sender, EventArgs e) 
    {
        // Code that runs when a new session is started
        string sessionId = Session.SessionID;
    }
    

    很容易。它起作用了!

        2
  •  19
  •   JoeBilly    15 年前

    出现此错误的原因如下:

    • 应用程序启动

    • 您使用的是global.asax,即使您在会话开始/结束事件中做了什么

    • 您的应用程序强制刷新响应太快

    • 你不能在冲水前使用会话

    它在尝试在发布时保存sessionid时由会话状态引发:

    System.Web.SessionState.SessionIDManager.SaveSessionID(HttpContext context, String id, Boolean& redirected, Boolean& cookieAdded)
    System.Web.SessionState.SessionStateModule.CreateSessionId()
    System.Web.SessionState.SessionStateModule.DelayedGetSessionId()
    System.Web.SessionState.SessionStateModule.ReleaseStateGetSessionID()
    System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs)
    System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
    

    我相信global.asax的存在会导致sessionstatemodule(延迟?)在发布时保存会话ID。即使在调用sessionid时没有使用会话来代替httpsessionstate。

    这就是为什么 字符串sessionid=session.sessionid; 技巧避免问题。

    我想它只出现在应用程序启动时,因为初始化行为。

    解决方案/技巧 :

    • 如前所述,避免在页面加载中刷新

    • 取消激活页面上的会话状态(启用会话状态)

    • 在冲洗前使用sessionid技巧

    • 如果不关心刷新后可能发生的错误,请使用response.end()代替.flush()。

        3
  •  6
  •   cjs    16 年前

    我相信这里的问题可能正是你在做一些事情导致页面输出 Page_Load ,根据 ASP.NET Page Lifecycle Overview 早在渲染阶段之前。

    确保在 PreRender 阶段。

        4
  •  3
  •   Gaz    15 年前

    我刚碰到这个问题,我想我会分享我的发现。

    web.config设置displaywhennewsession不相关,因为它只适用于codeplex上的一个特定的customcontrol(抱歉,我丢失了链接)。

    另一个建议似乎可以通过尽早初始化sessionid来工作。我使用Reflector深入研究了代码,不太明白这是如何避免这里的错误的,但它确实对我们有用!

    像大多数人一样,我们并没有在应用程序的任何地方显式地调用response.flush()。我们也在使用MVC作为记录。

        5
  •  0
  •   Michele La Ferla    10 年前

    我知道这很古老,但我发现了另一个可能适用于其他人的错误原因。如果您使用的是MVC(我使用的是带.NET 4.0的MVC 4),并且您将页面设置为不缓冲区 通过使用web.config元素

    <pages buffer="false">    
    

    然后,如果在代码中尝试将数据推送到会话对象中,则在子视图或执行会话状态访问的操作之前,如果页面已开始呈现,则可能会出现此错误。

    在这种情况下,可以通过将上面的缓冲区设置更改为true来修复错误。或者,将会话访问代码移动到主视图,而不是在子操作/子视图中。