ASP.NET MVC 3: Server cannot append header after HTTP headers have been sent

asp.netasp.net-mvc-2asp.net-mvc-3iis-express

We're busy upgrading an ASP.NET MVC 2 Application using the 3.5 framework to an ASP.NET MVC 3 Application running on the 4.0 framework.

There's a page which throws an exception when approached by using the browser back button. To support the browser back button on this page we implemented a system that requests the results for that page anew when arriving back on the page. I have no clear indications where to look for the problem however since I always only find the error

Server cannot append header after HTTP headers have been sent.

With stacktrace

at System.Web.HttpResponse.AppendHeader(String name, String value)
at System.Web.HttpResponseWrapper.AppendHeader(String name, String value)
at System.Web.Mvc.MvcHandler.AddVersionHeader(HttpContextBase httpContext)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<BeginProcessRequest>b__2()
at System.Web.Mvc.SecurityUtil.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a()
at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust[TResult](Func`1 func)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

How come the HTTP headers already have been sent?

Thank you in advance,
IvanL

EDIT:
I am adding new information and insight I gained while hunting for this problem. The Asynch Controller mention of one of the answers got me wondering. When I found that I had to change the following for the old MVC2 method to work:

[HttpPost, ValidateInput(false)]
public void SearchResultOverview(SearchResultViewModel model, string searchUrl)
{
    if (!string.IsNullOrEmpty(searchUrl))
    {
        searchUrl = searchUrl.Replace("SearchPartial", "SearchPartialInternal");

        //NOTE MVC 3
        HttpContext.Server.TransferRequest(searchUrl, true);

        //NOTE MVC 2
        //System.Web.HttpContext.Current.RewritePath(searchUrl, false);

        //IHttpHandler httpHandler = new MvcHttpHandler();
        //// Process request
        //httpHandler.ProcessRequest(System.Web.HttpContext.Current);
    }
}

When I looked up the TransferRequest method I found that it Performs an asynchronous execution of the specified URL and preserves query string parameters. ( http://msdn.microsoft.com/en-us/library/system.web.httpserverutility.transferrequest.aspx )

Also there is an Exception being thrown before the exception I posted (I simply missed out on it since I cought the exception late). This exception is:

The SessionStateTempDataProvider class requires session state to be enabled.
   at System.Web.Mvc.SessionStateTempDataProvider.SaveTempData(ControllerContext controllerContext, IDictionary`2 values)
   at System.Web.Mvc.TempDataDictionary.Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
   at System.Web.Mvc.Controller.PossiblySaveTempData()
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
   at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
   at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d()
   at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
   at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
   at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

So how do I make this work?

Best Answer

This can happen if buffering has been switched off on the page. Buffering means that asp.net waits for the whole request to be completed before sending the response. This means the header can be changed at any time. When buffering is off, the output is sent to the client as it's generated. You can't therefore change the headers at will, as they've already been sent.

From your stacktrace, it appears to be an async controller & I'm wondering if this has anything to do with it. I'm only guessing from what you've posted though.

Update

Correction, the async mention is actually framework code & nothing to do with your code. However from your code above, is SearchResultOverview an action on a controller? If so, then using the methods you are using to transfer execution is I think the cause of your problems.

It causing 2 mvchandlers to execute & they're interfering with each other. Routing would be a better way to redirect the request.

Related Topic