views:

3916

answers:

5

I'm getting this fault intermittently.

I found this link which summarises fairly well what I was able to find on the 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/

Basically it says you can try setting the web config setting DisplayWhenNewSession, or try kicking the session state thing into life by getting the Session.SessionID in the Session_OnStart.

But does anyone:

a) have an explanation for this

or even better, b) have a tried and tested fix

I realise that I can't flush the response after doing anything that would affect the http response header. If I did this it would cause an error every time but this is intermittent. The SessionID should surely be created by ASP.NET at the beginning of the page response automatically, before anything in the ASPX page or the Page_Load (which is where all my flushes are called).

Update: On reflection I realise this is happening when streaming a file down to the browser. Most of the browsers are actually search engine bots. I can recreate this error by starting a download and then closing the browser, so presumably the browsers are not waiting for the download to complete before cancelling the download operation. I have also seen this on other, normal pages, but 99% of the time it is download pages.

+1  A: 

I believe the issue here may be exactly that you're doing something to cause page output during Page_Load, which, according to the ASP.NET Page Lifecycle Overview is long before the rendering stage.

Ensure that you never do anything that could trigger page output until after the PreRender stage.

Curt Sampson
Thanks, I will have a look into at that tonight. Not sure why it would be intermittent though?
mike nelson
a conditional Response.Write() in an inappropriate event maybe?
Josh E
A: 

Having just run into this problem myself, I thought I'd share my findings.

The web.config setting DisplayWhenNewSession is irrelevant as it only applies to one particular customcontrol on Codeplex (sorry I've lost the link).

The other suggestion appears to work by initialising the SessionId early. I dug into the code using Reflector and couldn't quite see how this prevented the error here, but it certainly worked for us!

Like most people who seem to run into this bug, we are not explicitly calling Response.Flush() anywhere in the app. We are also using MVC, for the record.

Gaz
A: 

How did you " initialising the SessionId "

?

I am having the same problem and I am sure it will help me.

eitama
Sorry but I still haven't figured it out! I don't have a solution for this... yet....
mike nelson
+4  A: 

I have!

In the global.asax file you do this :

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

So easy. It works!

eitama
Is this a public/protected method - as it stands its private, I guess it should be protected. Is the sample complete, the fact that the sessionId is not saved, I presume is fine - its the triggering of the creation that is important, right?
Chris Kimpton
Thanks. I think this generally works so I will mark it as accepted answer, although I am not 100% sure. Can anyone comment please if they find a case where this doesn't work? Thanks.
mike nelson
+2  A: 

This error seems to appear when :

  • The application start

  • You're using a Global.asax even if you're doing something in the Session_Start / End events or not

  • Your application forces the Flush of the response too soon

  • You're not using the Session before the flush

It is raised by the session state when it try to save the sessionID on release :

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)

I believe the presence of Global.asax causes the session ID to be saved on release by the SessionStateModule (late?) even if no session have been used instead of HttpSessionState when SessionID is called.

It's the reason why string sessionId = Session.SessionID; trick avoid the problem.

I guess it only appears on application start because of initialization behaviors.

Solutions/tricks :

  • Avoid flushing in Page_Load as already said

  • Desactivate session state on the page (EnableSessionState)

  • Use the SessionID trick before the flush

  • Use Response.End() in place of .Flush() if you don't care about errors which can occur after your flush

JoeBilly