设置Response.StatusCode时,IIS7覆盖customErrors吗?


98

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

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

有没有其他人看到过这种行为,也许还知道如何解决?它在IIS6下工作,所以我不知道为什么事情会改变。

注意:这与ASP.NET Custom 404中的问题不同,返回200 OK,而不是找不到404。



Bobby,我实际上找到了这个问题并进行了尝试,但是并没有解决问题。但是,谢谢。
尼古拉斯

我想评论一下,从经典流水线转换为集成流水线时也会发生此问题。我使用了@PavelChuchuva解决方案(@RickStrahl解决方案也可以使用)。我猜“直通”经典是自动的,在集成需要服务器的全局错误页面处理..
sonjz

Answers:


116

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

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

existingResponse属性的默认值为Auto:

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

详细信息:IIS7自定义错误模块会带来什么


3
请注意,将existingResponse设置为PassThrough可能会导致一些副作用。在进行任何更改之前,请先掌握Pavel提供的链接。
Lex Li

<httpErrors existingResponse="PassThrough" />相当于Response.TrySkipIisCustomErrors或者他们不同的表现?
阿斯比昂·乌尔斯贝格

1
@sbjornu它们实现了相同的目的,但是通过Response.TrySkipIisCustomErrors您可以更好地控制何时显示IIS自定义错误。
Pavel Chuchuva

谢谢,我已经看到了很多有关response.tryskipiiscustomerrors的信息,但关于现有响应的信息却很少。
HBCondo '02

我仅通过设置existingResponse =“ Auto”就解决了自定义错误页面无法在运行IIS7的Web主机上运行的问题,这非常令人惊讶,因为该文章引用的是默认值。显然不是……或者我的托管公司在其他地方设置了错误的默认值。无论哪种方式,我都希望可以节省一个人几个小时:\
Eric Sassaman

80

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

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

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

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


2
这对我也不起作用(IIS8),并且该建议似乎与OP不匹配(假设我正确阅读了它)。我想要customError配置在web.config中触发。与Response.TrySkipIisCustomErrors = true我得到相同的行为:显示丑陋的服务器生成的错误页面。将其设置为false没有任何反应-空白的浏览器窗口。
肖恩·南

对我来说很好!尽管Pavel Chuchuva在回答中提到的设置也很有效,但它有一些副作用,导致了其他问题。此设置使我可以在想要的特定情况下跳过IIS错误覆盖,而对于其他所有情况则保持原样。
凯文·提格

对我来说,在Azure中运行良好。服务器标头Server:Microsoft-IIS/8.5 X-AspNet-Version:4.0.30319 X-AspNetMvc-Version:5.2 X-Powered-By:ASP.NET
oxfn 2015年

我仍然发现需要为此设置customErrors mode="Off"工作。如果我这样做了,那么当我在此答案中使用代码时,httpErrors existingResponse =“ Auto”(默认值)对我来说正常工作。
AaronLS

11

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


1
尽管此答案被标记为答案,但我认为值得一读其他答复以获取对该主题的更多见解。
Lex Li

另外,删除可能会很好。FilterConfig中的HandleErrorAttribute
每G

4

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

首先,因为我有一个自定义的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状态代码,除非它实际上是一个无效页面。

无论如何,这就是我的方法。希望能对某人有所帮助。


3

这个问题一直令人头疼。前面提到的所有建议都没有一个能为我解决,因此,我将其包括在内。作为记录,我们的环境/平台使用:

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

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

首先,我的代码必须抛出HttpExceptionNotFoundResult从控制器返回a 并没有达到我想要的结果。

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

然后,我不得不配置customErrorshttpError在Web.config节点。

<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>

请注意,我留下了existingResponseas Auto,这与提供的@sefl解决方案不同。

customErrors设置似乎是必要处理我明确地抛出HttpException,而httpErrors节点处理,即下跌Globals.asax.cs指定的路由模式之外的URL。

PS使用这些设置,我不需要设置 Response.TrySkipIisCustomErrors


2

TrySkipIisCustomErrors只是一个难题的一部分。如果您使用“自定义错误页面”,但您还希望基于4xx状态交付一些RESTful内容,那么您将遇到问题。将web.config的httpErrors.existingResponse设置为“自动”不起作用,因为.net似乎总是向IIS提供某些页面内容,因此,使用“自动”将导致不使用所有(或至少一些)自定义错误页面。使用“替换”也不会起作用,因为响应将包含您的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,因此仍有一些空间可以改进此代码。


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

进一步的调查显示,我的处理方式有误-如果您看到的是不同的错误消息,则默认情况下,详细消息不是默认情况下的,但可能已打开。


Response.StatusCode是一个整数,因此除了“ 404”之外,我看不到一种设置更具体代码的方法。我已经将IIS7配置为使用/显示自定义错误页面,如您的URL所示。
尼古拉斯

嗯...很遗憾,由于我不在家用电脑上,因此目前无法测试。如果到那时您还没有解决方案-今晚我来看一下。
nullnvoid
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.