2009-01-12 50 views
93

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

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

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

注:这是不一样的问题ASP.NET Custom 404 Returning 200 OK Instead of 404 Not Found

+0

我有同样的问题。已经在这里回答[http://stackoverflow.com/questions/347281/asp-net-custom-404-returning-200-ok-instead-of-404-not-found](http://stackoverflow.com/questions/347281/ASP净定制-404-返回-200-OK-代替-的-404未找到)。 – 2009-01-12 02:54:37

+0

鲍比,我实际上发现了这个问题并试了一下,但没有解决问题。但是,谢谢。 – 2009-01-12 03:37:40

+0

我想评论说,从Classic切换到Integrated Pipeine时也会发生此问题。我用@PavelChuchuva解决方案(@RickStrahl解决方案也可以)。我猜Classic中的“passthrough”是自动的,在Integrated中需要服务器的全局错误页面处理。 – sonjz 2015-01-16 02:02:32

回答

78

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

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

通常你应该在处理您的应用程序错误处理程序不捕获所有的错误你的Application_Error处理程序做到这一点。

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

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

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

+0

Response.StatusCode是一个整数,所以我没有看到设置更具体的代码的方式,而不仅仅是“ 404" 。我已将IIS7配置为使用/显示自定义错误页面,如您的URL所示。 – 2009-01-12 03:45:01

+0

嗯...不幸的是我现在无法测试,因为我不在家用电脑上。如果到那时你还没有解决方案 - 我今晚会看看。 – nullnvoid 2009-01-12 03:49:24

113

设置existingResponse给直通在system.webServer/httpErrors部分:existingResponse财产

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

默认值是自动:

Auto tells custom error module to do the right thing. Actual error text seen by clients will be affected depending on value of fTrySkipCustomErrors returned in IHttpResponse::GetStatus call. When fTrySkipCustomErrors is set to true, custom error module will let the response pass through but if it is set to false, custom errors module replaces text with its own text.

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

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> 

从那里,我加入到这个Application_Error事件在Global.asax中:

Response.TrySkipIisCustomErrors = True 

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

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

3

这个问题一直是一个令人头痛的问题。前面提到的任何建议都不能解决它,所以我包括我的解决方案。为了记录在案,我们的环境/平台使用:

  • .NET框架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> 

注意,我离开了existingResponseAuto,这比提供的解决方案@sefl不同。

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

P.S.有了这些设置,我不需要设置Response.TrySkipIisCustomErrors

0

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

所以,如果你想跳过CEP某些情况下(通过绕过我的意思是返回状态4XX一些内容),就需要额外的步骤:如果你想使用REST

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

所以:清除错误响应(即400 - 错误请求)并发送一些内容,您只需要在某处设置TrySkipIisCustomErrors,并在web.config的httpErrors部分中将existingResponse设置为“自动”。现在:

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

如果你想返回状态为空的内容从你的行动它将被视为一个空的答复和CEP将被显示,所以有一些空间来改善这个代码。