IIS7在设置Response.StatusCode时覆盖customErrors?

时间:2009-01-12 02:37:57

标签: asp.net iis-7

这里有一个奇怪的问题。每个人都知道,如果您使用web.config的customErrors部分来创建自定义错误页面,那么您应该将Response.StatusCode设置为适当的。例如,如果我创建一个自定义404页面并将其命名为404.aspx,我可以将<% Response.StatusCode = 404 %>放在内容中,以使其具有真正的404状态标题。

到目前为止跟我来?好。现在尝试在IIS7上执行此操作。期间我无法上班。如果在自定义错误页面中设置了Response.StatusCode,则IIS7似乎完全覆盖自定义错误页面,并显示其自己的状态页面(如果已配置一个。)

有没有其他人看过这种行为,也许还知道如何解决这个问题?它在IIS6下运行,所以我不知道为什么会发生变化。

注意:这与ASP.NET Custom 404 Returning 200 OK Instead of 404 Not Found

中的问题不同

7 个答案:

答案 0 :(得分:115)

在system.webServer / httpErrors部分中将existingResponse设置为PassThrough:

  <system.webServer>
    <httpErrors existingResponse="PassThrough" />
  </system.webServer>

existingResponse属性的默认值为Auto:

  

自动告诉自定义错误模块执行正确事情。客户端看到的实际错误文本将受到影响,具体取决于IHttpResponse::GetStatus调用中返回的fTrySkipCustomErrors的值。当fTrySkipCustomErrors设置为true时,自定义错误模块将允许响应通过,但如果将其设置为false,则自定义错误模块将使用其自己的文本替换文本。

更多信息:What to expect from IIS7 custom error module

答案 1 :(得分:80)

使行为保持一致的最简单方法是清除错误并使用Response.TrySkipIisCustomErrors并将其设置为true。这将覆盖页面内的IIS全局错误页面处理或Application_Error中的全局错误处理程序。

Server.ClearError();
Response.TrySkipIisCustomErrors = true;

通常,您应该在Application_Error处理程序中执行此操作,该处理程序处理应用程序错误处理程序未捕获的所有错误。

更多详细信息可以在这篇博文中找到: http://www.west-wind.com/weblog/posts/745738.aspx

答案 2 :(得分:11)

已解决:事实证明,“详细错误”需要打开才能使IIS7“直通”您可能遇到的任何错误页面。见http://forums.iis.net/t/1146653.aspx

答案 3 :(得分:4)

我不确定这在性质上是否相似,但我解决了表面上听起来类似的问题,这就是我处理它的方式。

首先,在我的情况下,existingResponse(Auto)的默认值是正确的答案,因为我有一个自定义的404,400和500(我可以创建其他的,但这三个就足够了我正在做的事情) )。以下是帮助我的相关部分。

来自web.config:

<customErrors mode="Off" />

<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
  <clear />
  <error statusCode="404" path="/errors/404.aspx" responseMode="ExecuteURL" />
  <error statusCode="500" path="/errors/500.aspx" responseMode="ExecuteURL" />
  <error statusCode="400" path="/errors/400.aspx" responseMode="ExecuteURL" />
</httpErrors>

从那里,我将其添加到global.asax上的Application_Error:

    Response.TrySkipIisCustomErrors = True

在我的每个自定义错误页面上,我必须包含正确的响应状态代码。在我的情况下,我使用自定义404将用户发送到我网站的不同部分,因此我希望返回404状态代码,除非它实际上是一个死页。

无论如何,我就是这样做的。希望有所帮助。

答案 4 :(得分:3)

这个问题一直是个头疼的问题。单独前面提到的建议都没有为我解决,所以我包括我的解决方案。为了记录,我们的环境/平台使用:

  • .NET Framework 4
  • MVC 3
  • IIS8(工作站)和IIS7(Web服务器)

具体来说,我试图获得一个HTTP 404响应,将用户重定向到我们的自定义404页面(通过Web.config设置)。

首先,我的代码必须抛出HttpException。从控制器返回NotFoundResult并未达到我所追求的结果。

throw new HttpException(404, "There is no class with that subject");

然后我必须在Web.config中配置两个 customErrorshttpError个节点。

<customErrors mode="On" defaultRedirect="/classes/Error.aspx">
  <error statusCode="404" redirect="/classes/404.html" />
</customErrors>

...

<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
  <clear />
  <error statusCode="404" path="/classes/404.aspx" responseMode="ExecuteURL" />
</httpErrors>

请注意,我将existingResponse保留为Auto,这与@sefl提供的解决方案不同。

customErrors设置似乎是处理我明确抛出的HttpException所必需的,而httpErrors节点处理的URL超出了Globals.asax.cs中指定的路由模式。

P.S。使用这些设置,我无需设置Response.TrySkipIisCustomErrors

答案 5 :(得分:0)

默认情况下,IIS 7使用详细的自定义错误消息,因此我认为Response.StatusCode将等于404.XX而不仅仅是404.

您可以将IIS7配置为使用更简单的错误消息代码或修改代码,以处理IIS7提供的更详细的错误消息。

此处提供更多信息: http://blogs.iis.net/rakkimk/archive/2008/10/03/iis7-enabling-custom-error-pages.aspx

进一步的调查显示我的方法是错误的 - 如果你看到你提到的不同的错误信息,详细的信息不是默认的,但也许它们已经在你的盒子上打开了。

答案 6 :(得分:0)

TrySkipIisCustomErrors只是谜题的一部分。如果您使用自定义错误页面,但您还想根据4xx状态提供一些RESTful内容,那么您就遇到了问题。将web.config的httpErrors.existingResponse设置为“Auto”不起作用,因为.net似乎总是向IIS提供一些页面内容,因此使用“Auto”会导致不使用所有(或至少一些)自定义错误页面。使用“替换”也不起作用,因为响应将包含您的http状态代码,但其内容将为空或填充自定义错误页面。事实上,“PassThrough”会关闭CEP,因此无法使用。

因此,如果您想在某些情况下绕过CEP(通过绕过我的意思是返回状态4xx并包含一些内容),您将需要额外的步骤:清除错误:

void Application_Error(object sender, EventArgs e)
{
    var httpException = Context.Server.GetLastError() as HttpException;
    var statusCode = httpException != null ? httpException.GetHttpCode() : (int)HttpStatusCode.InternalServerError;

    Context.Server.ClearError();
    Context.Response.StatusCode = statusCode;
}

因此,如果您想使用REST响应(即400 - 错误请求)并使用它发送一些内容,您只需要在某个地方设置TrySkipIisCustomErrors并将existingResponse设置为“自动”在web.config的httpErrors部分中。现在:

  • 当没有错误时(操作返回4xx或5xx)并返回一些内容,不使用CEP并将内容传递给客户端;
  • 当出现错误(抛出异常)时,错误处理程序返回的内容将被删除,因此使用了CEP。

如果你想从你的行动中返回空内容的状态,它将被视为空响应并显示CEP,因此有一些空间来改进这段代码。