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


79

我间歇性地遇到此故障。

我发现此链接可以很好地概括我在Google上可以找到的内容:http : //www.wacdesigns.com/2009/02/03/session-state-has-created-a-session-id-but-无法保存它,因为该响应已被应用程序刷新/

基本上,它说您可以尝试设置Web配置设置DisplayWhenNewSession,或者通过在Session_OnStart中获取Session.SessionID来尝试激活会话状态。

但是有人吗:

a)对此有一个解释

甚至更好,b)具有经过测试的修复

我意识到在执行可能会影响http响应标头的所有操作后,我无法刷新响应。如果我这样做,每次都会导致错误,但这是间歇性的。当然,SessionID应该由ASP.NET在页面响应开始时自动创建,而不是在ASPX页面或Page_Load(调用我的所有刷新的位置)之前创建。

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


1
我有完全一样的问题。我完全看到它的唯一原因是当我将异常处理放入Global.asax中时。这是非常断断续续的。如果有人知道答案,那就太好了!
Scott Ferguson

6
现在链接已断开:-(
Casebash 2011年

Answers:


84

我有!

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

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

太简单。有用!


这是一种公共/受保护的方法吗?因为它是私有的,所以我认为它应该受到保护。我认为示例是否完整,没有保存sessionId的事实,它的创建很重要,对吧?
克里斯·金普顿

谢谢。我认为这通常可行,因此尽管我不确定100%,但我会将其标记为可接受的答案。如果有人发现这种情况不起作用,任何人都可以发表评论吗?谢谢。
迈克·内尔森

我只是将此方法添加到我的global.asax文件中,它摆脱了我的错误消息,该错误消息与问题相同,非常感谢eitama!
vanhornRF 2011年

这解决了我的问题(我强迫冲洗),但是您知道为什么这可以作为解决方案吗?
2013年

这个答案为我节省了许多时间。永远不会猜到。谢谢!
HockeyJ 2014年

23

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

  • 申请开始

  • 您正在使用Global.asax,即使您是否在Session_Start / End事件中进行了某些操作

  • 您的应用程序过早强制刷新响应

  • 您在刷新之前没有使用Session

当尝试在release上保存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时也是如此。

这就是字符串sessionId = Session.SessionID;的原因绝招避免问题。

我猜它只是由于初始化行为而出现在应用程序启动时。

解决方案/技巧

  • 如前所述,避免在Page_Load中刷新

  • 在页面上停用会话状态(EnableSessionState)

  • 在刷新之前使用SessionID技巧

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


6

我相信这里的问题可能恰好是您正在做一些事情导致Page期间的页面输出Page_Load,根据ASP.NET Page Lifecycle Overview的说法,该阶段早于呈现阶段。

确保直到该PreRender阶段之后,您才做任何可能触发页面输出的操作。


谢谢,今晚我将进行调查。不确定为什么会断断续续吗?
麦克尼尔森

一个不合适的事件中的条件Response.Write()可能吗?
乔什E

3

我自己刚遇到这个问题,我想分享一下我的发现。

web.config设置DisplayWhenNewSession无关紧要,因为它仅适用于Codeplex上的一个特定customcontrol(对不起,我已经失去了链接)。

另一个建议似乎可以通过尽早初始化SessionId来起作用。我使用Reflector仔细研究了代码,在这里看不到如何防止错误发生,但是它确实对我们有用!

就像大多数似乎会遇到此错误的人一样,我们并未在应用程序中的任何位置显式调用Response.Flush()。我们也使用MVC作记录。


0

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

<pages buffer="false">    

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.