5

Occasoinally i get this exception thrown (viewable in elmah)

System.Web.HttpException: 
Server cannot append header after HTTP headers have been sent.

System.Reflection.TargetInvocationException: Exception has been thrown by the target 
of an invocation. ---> System.Web.HttpException: Server cannot append header after 
HTTP headers have been sent.
   at System.Web.HttpHeaderCollection.SetHeader(String name, String value, 
       Boolean replace)
   at System.Web.HttpHeaderCollection.Add(String name, String value)
   at BettingOnYou.MvcApplication.Application_EndRequest() in /Global.asax.cs:line 55

This line corresponds to:

protected void Application_EndRequest()
{
    // By default, IE renders pages on the intranet (same subnet) in compatibility mode.  
    // IE=edge forces IE to render in it's moststandard mode possible.  
    // IE8 Standards in IE8, IE9 Standardss in IE9, etc..
    //
    // Chrome=1 causes ChromeFrame to load, if installed.  This allows IE6 to use
    // a Chrome frame to render nicely.
    Response.Headers.Add("X-UA-Compatible", "IE=edge, Chrome=1");
}

Is there a more appropriate place to do this? I know the EndRequest seems kind of odd, but every example of people using this places it here.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • Have you tried adding it in `Application_BeginRequest`? The error is caused by trying to modify the headers after content has already been sent to the client. Putting it in begin request should stop the error. – adrianbanks Aug 25 '11 at 23:15
  • @adrianbanks - I'm aware of why the exception occurs, however I'm trying to add the header at the last stage of the pipeline before headers are sent. EndRequest is supposed to happen before Headers get sent, the next step in the pipeline is PreRequestSendHeaders. So, it doesn't make much sense how headers are being sent already. – Erik Funkenbusch Aug 26 '11 at 14:25

2 Answers2

3

Application_BeginRequest would be a better place to do it. Unless maybe you have some reason somewhere else in your application for waiting until the end, though I can't think of a good reason in common cases.

If you really want to keep it in Application_EndRequest, you can turn on output buffering (Response.BufferOutput = true; somewhere early, like in Page_Load) so headers aren't sent until the request is completely processed. There are pros and cons to output buffering though, so make sure you read up on that if you want to try it.

Jon Adams
  • 24,464
  • 18
  • 82
  • 120
0

For the benefit of those landing here, there's another way of adding X-UA-Compatible (or any other such header). You can also include X-UA-Compatible as a meta tag in your master page OR default.cshtml like so:

<meta http-equiv="X-UA-Compatible" content="IE=Edge" />

This technique is the easiest to implement especially on shared hosting where you may not be able to tweak IIS settings too easily. A great discussion on stackoverflow can be found here.

Community
  • 1
  • 1
Sudhanshu Mishra
  • 6,523
  • 2
  • 59
  • 76
  • While you can do this, it's sporatic as to whether it will work or not. In addition, it must appear within the first 1024 bytes of the rendered page or it will be ignored. What's more, this only causes a document compatibility change, and not the browsermode to change because by the time the browser has started rendering the content, it's already chosen it's browser mode. Using the header approach is the most foolproof. – Erik Funkenbusch Jul 27 '15 at 04:11
  • @ErikFunkenbusch I've tried this in the head section of the page and found it to work as expected. Still reading up on the brwosermode bit, but as per this thread http://stackoverflow.com/questions/17871124/how-to-bring-back-browser-mode-in-ie11 when I check IE 11 dev tools, setting the said header does select Edge. Am I completely off track? – Sudhanshu Mishra Jul 27 '15 at 04:58
  • The difference is in the user agent string sent to the server. with the header mode, the user agent string is whatever you specify (IE8, IE9, etc..) but that's not possible with the meta tag because the user agent string has already been sent by the time the browser reads the meta tag. So, even though you may be saying to render in IE8 mode, the browser will still say it's IE10 or IE11 when using the meta tag. – Erik Funkenbusch Jul 27 '15 at 05:48
  • @ErikFunkenbusch Is this true even if the response.buffer is set to true? (I know that it is not always advisable to do this, but just curious) – Sudhanshu Mishra Jul 27 '15 at 05:50