【发布时间】:2012-01-20 11:43:13
【问题描述】:
我们正忙着将使用 3.5 框架的 ASP.NET MVC 2 应用程序升级到在 4.0 框架上运行的 ASP.NET MVC 3 应用程序。
有一个页面在使用浏览器后退按钮访问时会引发异常。为了支持此页面上的浏览器后退按钮,我们实现了一个系统,该系统在返回页面时重新请求该页面的结果。我没有明确的指示在哪里寻找问题,但是因为我总是只找到错误
Server cannot append header after HTTP headers have been sent.
使用堆栈跟踪
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)
为什么已经发送了 HTTP 标头?
提前谢谢你, 伊万L
编辑: 我正在添加在寻找这个问题时获得的新信息和见解。提到其中一个答案的异步控制器让我想知道。当我发现我必须更改以下内容才能使旧的 MVC2 方法起作用时:
[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);
}
}
当我查看 TransferRequest 方法时,我发现它是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)
在我发布异常之前还有一个异常被抛出(我只是错过了它,因为我很晚才咳出异常)。这个例外是:
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)
那么我该如何做呢?
【问题讨论】:
-
好吧,让我看看我能不能从心理上推断出这个…………嗯……不……你必须提供一些代码。您要附加哪些标头,何时附加?
-
@Mystere Man:这正是重点。我自己没有附加任何标题,似乎从 MVC2 更改为 MVC3 会产生这个问题,因为代码运行良好,在 MVC2 中没有任何异常。如果您查看堆栈跟踪,您会注意到:
at System.Web.Mvc.MvcHandler.AddVersionHeader(HttpContextBase httpContext)这意味着 MVC 本身正在尝试添加标头,但它不能。我确实尝试了您将我与reponse.BufferOutput = true联系起来的问题的解决方案,但它不起作用。我总是收到这个异常和堆栈跟踪。 -
为什么要在 action 方法中创建一个新的 HttpHandler?
-
@Andrew Barber:这样做是为了处理大型 URL。字符串 searchUrl 是实际的 URL,但它太大以至于一些浏览器拒绝使用它。为了规避这一点,URL 实际上已发布并在内部处理。在 MVC 2 中,这是通过启动一个新的请求处理程序并让它处理实际 URL 来完成的,因为 MVC 3 这不再可能,我为此找到的解决方案是使用
Server.TransferRequest()。然而,当浏览器后退按钮接近时,这种方法似乎不起作用......(当页面定期加载时它完美地起作用)
标签: asp.net asp.net-mvc-3 asp.net-mvc-2 iis-express