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

问题描述 投票:97回答: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中的问题不同

asp.net iis-7
7个回答
115
投票

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

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

existingResponse属性的默认值为Auto:

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

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


80
投票

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

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

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

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


11
投票

解决:事实证明,“详细错误”需要打开,以便IIS 7“通过”您可能拥有的任何错误页面。看到qazxsw poi


4
投票

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

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

来自web.config:

http://forums.iis.net/t/1146653.aspx

<customErrors mode="Off" />

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

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

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

无论如何,我就是这样做的。希望能帮助别人。


3
投票

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

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

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

首先,我的代码必须扔一个 Response.TrySkipIisCustomErrors = True 。从控制器返回HttpException并没有达到我追求的结果。

NotFoundResult

然后我必须在Web.config中配置throw new HttpException(404, "There is no class with that subject"); customErrors节点。

httpError

...

<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,这与@sefl提供的解决方案不同。

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

附:通过这些设置,我不需要设置httpErrors


0
投票

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

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

更多信息在这里:Response.TrySkipIisCustomErrors

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


0
投票

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

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

TrySkipIisCustomErrors

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

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

如果您想从您的操作中返回包含空内容的状态,则会将其视为空响应并显示CEP,因此有一些空间可以改进此代码。

© www.soinside.com 2019 - 2024. All rights reserved.