什么导致“会话状态已经创build了一个会话ID,但无法保存,因为应答已经被刷新了。”

我间歇性地得到这个错误。

我发现这个链接,它总结了我在Google上能find的东西: http : //www.wacdesigns.com/2009/02/03/session-state-has-created-a-session-id-but-不能保存,它-因为最响应是,已经刷新由这应用程序/

基本上它说你可以尝试设置Webconfiguration设置DisplayWhenNewSession,或者通过Session_OnStart获取Session.SessionID来尝试踢会话状态的东西。

但是有没有人:

a)对此有一个解释

甚至更好,b)有一个经过validation的修复

我意识到,在做任何会影响http响应头的东西之后,我都无法刷新响应。 如果我这样做, 每次都会导致错误,但这是间歇性的。 在ASPX页面或Page_Load(这是我所有的刷新被调用的地方)之前,会自动在页面响应开始时由ASP.NET创buildSessionID。

更新:在反思时,我意识到这是发生在stream文件到浏览器。 大多数浏览器实际上是search引擎机器人。 我可以通过开始下载然后closures浏览器来重新创build这个错误,所以大概浏览器在取消下载操作之前不会等待下载完成。 我也在其他正常页面上看到了这一点,但99%的时间是下载页面。

我有!

在global.asax文件中,您可以这样做:

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

太简单。 有用!

这个错误似乎出现在:

  • 应用程序启动

  • 即使您在Session_Start / End事件中做了某些事情,您也正在使用Global.asax

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

  • 在冲洗之前,您没有使用会话

当它尝试在发布时保存会话ID时,会话状态引发:

 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。

这就是为什么stringsessionId = Session.SessionID; 把戏避免了这个问题。

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

解决scheme/技巧

  • 避免像已经说过的那样在Page_Load中刷新

  • 禁用页面上的会话状态(EnableSessionState)

  • 在刷新之前使用SessionID技巧

  • 使用Response.End()代替.Flush(),如果您不关心在刷新后可能发生的错误

我相信这里的问题可能正是你在做一些事情来在Page_Load期间导致页面输出,根据ASP.NET页面生命周期概述,它早在渲染阶段之前。

确保你从不做任何可能触发页面输出的事情,直到PreRender阶段。

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

web.config设置DisplayWhenNewSession是无关的,因为它只适用于Codeplex上的一个特定的自定义控件(对不起,我已经失去了链接)。

另一个build议似乎是早期初始化SessionId。 我使用reflection器挖入代码,并不能完全看到这是如何防止这里的错误,但它确实为我们工作!

就像大多数似乎遇到这个bug的人一样,我们没有明确地调用应用程序中的任何地方的Response.Flush()。 我们也使用MVC进行logging。

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

 <pages buffer="false"> 

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

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