asp.net 导致“会话状态已创建会话ID,但无法保存它,因为响应已被应用程序刷新,”

mwecs4sa  于 2023-10-21  发布在  .NET
关注(0)|答案(5)|浏览(166)

我间歇性地得到这个错误。
我发现这个链接很好地总结了我在Google上找到的内容: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_OnStart中获取Session.SessionID来激活会话状态。
但是否有人:
(一)对此作出解释
或者更好,b)有一个久经考验的解决方案,
我意识到我不能在做任何会影响http响应头的事情后刷新响应。如果我这样做,它会导致错误 * 每次 *,但这是间歇性的。SessionID肯定应该由ASP.NET在页面响应的开始自动创建,在ASPX页面或Page_Load(这是我所有刷新的调用)中的任何内容之前。

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

p4rjhz4m

p4rjhz4m1#

我有!
在global.asax文件中,您可以执行以下操作:

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

太简单了。成功了!

wvt8vs2t

wvt8vs2t2#

此错误似乎在以下情况下出现:

  • 涂布开始
  • 无论是否在Session_Start / End事件中执行某些操作,都使用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的存在会导致会话ID在发布时由SessionStateModule保存(晚?),即使在调用SessionID时没有使用会话而不是HttpSessionState。
这就是为什么string sessionId = Session.SessionID;技巧避免这个问题的原因。
我猜它只出现在应用程序启动时,因为初始化行为。

解决方案/技巧

  • 如前所述,避免在Page_Load中刷新
  • 取消激活页面上的会话状态(EnableSessionState)
  • Web.config中添加<system.web> <sessionState mode="Off" /> </system.web>
  • 在刷新之前使用SessionID技巧
  • 如果你不关心刷新后可能发生的错误,可以使用Response.End()代替.Flush()
9nvpjoqh

9nvpjoqh3#

我相信这里的问题可能正是您正在做一些事情来导致Page_Load期间的页面输出,根据ASP.NET Page Lifecycle Overview,这是在渲染阶段之前很久。
确保在PreRender阶段之前,不要执行任何可能触发页面输出的操作。

w8f9ii69

w8f9ii694#

我自己刚刚遇到这个问题,我想我应该分享我的发现。
web.config设置DisplayWhenNewSession是不相关的,因为它只适用于Codeplex上的一个特定的自定义控件(对不起,我失去了链接)。
另一个建议似乎可以通过尽早初始化SessionId来工作。我使用Reflector深入研究了代码,不太明白这是如何防止这里的错误的,但它确实对我们有效!
像大多数遇到这个bug的人一样,我们没有在应用程序的任何地方显式调用Response.Flush()。我们也在使用MVC,为了记录。

aor9mmx1

aor9mmx15#

我承认这是非常古老的,但我发现了另一个可能适用于其他人的错误原因。如果您使用MVC(我使用的是MVC 4和.Net 4.0),并且您使用web.config元素将页面设置为不缓冲

<pages buffer="false">

然后,如果在您的代码中尝试将数据推入会话对象,则如果页面在您的子视图或操作执行会话状态访问之前已开始呈现,则可能会出现此错误。
在这种情况下,您可以通过将上面的缓冲区设置更改为true来修复错误。或者,将会话访问代码移动到主视图中,而不是子操作/子视图中。

相关问题