服务器在发送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浪的原因:
- 您的操作正在执行,将标记写入响应stream
- 在标记写入开始之前,该stream没有缓冲,强制响应头被写入。
- 您的视图遇到运行时错误
- exception处理程序试图将状态码设置为其他非200
- 由于标题已经发送失败。
如果我不同意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)
我知道我的答案基本上是重复这里已经说过的,但是有时候很难弄清楚这个覆盖是在哪里发生的。