服务器在发送HTTP头之后不能设置状态IIS7.5

有时我在生产环境中遇到exception情况:

  • 处理信息
    • 进程ID:3832
    • 进程名称:w3wp.exe
    • 帐户名称:NT AUTHORITY \ NETWORK SERVICE
  • 例外信息
    • exceptiontypes:System.Web.HttpException
    • exception消息: 服务器在发送HTTP头之后无法设置状态。
  • 请求信息
    • 请求url: http : //www.myulr.pl/logon
    • 请求path:/login
    • 用户主机地址:10.11.9.1
    • 用户:user001
    • 通过身份validation:是
    • authenticationtypes:表单
    • 线程帐户名称:NT AUTHORITY \ NETWORK SERVICE
  • 线程信息
    • 线程ID:10
    • 线程帐户名称:NT AUTHORITY \ NETWORK SERVICE
    • 假冒:假
Stack trace: at System.Web.HttpResponse.set_StatusCode(Int32 value) at System.Web.HttpResponseWrapper.set_StatusCode(Int32 value) at System.Web.Mvc.HandleErrorAttribute.OnException(ExceptionContext filterContext) at System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList(1) filters, Exception exception) at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) at System.Web.Mvc.Controller.ExecuteCore() at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4() 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.EndProcessRequest(IAsyncResult asyncResult) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& ompletedSynchronously) 

我没有注意到我的testing环境中的这个错误,我应该检查什么?

我正在使用ASP.NET MVC 2(Release Candidate 2)

我会广泛地同意stream浪的原因:

  1. 您的操作正在执行,将标记写入响应stream
  2. 在标记写入开始之前,该stream没有缓冲,强制响应头被写入。
  3. 您的视图遇到运行时错误
  4. exception处理程序试图将状态码设置为其他非200
  5. 由于标题已经发送失败。

如果我不同意Vagrant是“原因没有绑定错误”的补救措施 – 你仍然可以在View绑定中遇到运行时错误,例如空引用exception。

更好的解决scheme是确保Response.BufferOutput = true; 之前任何字节发送到响应stream。 例如在您的控制器操作或应用程序中的On_Begin_Request中。 这使得服务器传输,cookies /头文件被设置等等自然结束响应,或者调用结束/刷新。

当然也要检查缓冲区是否被刷新/设置为false在堆栈中进一步下降。

MSDN参考: HttpResponse.BufferOutput

只是添加到上面的答复。 当我第一次开始使用ASP.Net MVC时,我有同样的问题,我正在做一个Response.Redirect控制器操作过程中:

 Response.Redirect("/blah", true); 

而不是返回一个Response.Redirect行动,我应该已经返回一个RedirectAction

 return Redirect("/blah"); 

HTTP服务器不会将响应头发送回客户端,直到您指定错误或者您开始​​发送数据。 如果您开始将数据发送回客户端,则服务器必须首先发送响应头(其中包含状态码)。 一旦头被发送,显然你不能再在头上放置一个状态码。

这是通常的问题。 你启动页面,并发送一些初始标签(即<head> )。 然后,服务器首先发送带有假定SUCCESS状态的HTTP响应头,然后将这些标签发送给客户端。 现在你开始研究页面的内容,发现一个问题。 此时您不能发送错误,因为已经发送了包含错误状态的响应标头。

解决方法是:在生成任何内容之前,检查是否有任何错误。 只有这样,当你确信没有问题时,你才可以开始发送内容,比如标签。

在你的情况,似乎你有一个login页面处理来自表单的POST请求。 你可能会抛出一些初始的HTML,然后检查用户名和密码是否有效。 相反,您应该首先validation用户名/密码,然后再生成任何 HTML。

我有与设置StatusCode相同的问题,然后在AuthorizeAttribute HandleUnauthorizedRequest方法Response.End

 var ctx = filterContext.HttpContext; ctx.Response.StatusCode = (int)HttpStatusCode.Forbidden; ctx.Response.End(); 

如果您使用的是.NET 4.5+,请在Response.StatusCode之前添加此行

 filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true; 

如果您使用.NET 4.0,请尝试SuppressFormsAuthenticationRedirectModule 。

在做redirect之前检查这个怎么样:

 if (!Response.IsRequestBeingRedirected) { //do the redirect } 

你实际上是试图redirect一个有一些响应抛出的页面。 因此,首先在页面的开始处使用response.buffer = true保留已经放入缓冲区的信息,然后在需要时使用response.flush刷新此错误将得到修复

我记得这个exception的部分:在PHP中出现的“无法修改头文件信息 – 已经发送的头文件”。 发生在redirect阶段的头文件已经被发送,并且产生了其他的输出,例如:

回声“你好”; 标题(“位置: http : //stackoverflow.com ”);

如果我错了,请原谅我,纠正我,但我还在学习MS Technologies,我正在努力帮助。

我很抱歉,但是我将我的2美分添加到线程以防万一任何人有同样的问题。

  • 我在我的MVC应用程序中使用表单身份validation
  • 但是一些控制器操作是“匿名的”,即允许未经authentication的用户
  • 有时在这些行动中,我仍然希望用户在某些情况下被redirect到login表单
  • 做到这一点 – 我有我的行动方法: return new HttpStatusCodeResult(401) – 和ASP.NET是超级好,检测到这一点,它将用户redirect到login页面! 魔术吧? 它甚至有适当的ReturnUrl参数等

但是你知道我在哪里? 我回到401 。 而ASP.NETredirect用户。 这基本上是回报302 。 一个状态码被replace为另一个状态码。

而一些IIS服务器(只是一些!)抛出这个exception。 有些不是。 – 我的testingserevr没有,只有在我的生产服务器上(是不是总是这样的权利o_O)

我知道我的答案基本上是重复这里已经说过的,但是有时候很难弄清楚这个覆盖是在哪里发生的。