对于400个错误中的某些错误,不会显示ASP.NET MVC customError页面

我对新的ASP.NET MVC应用程序的自定义错误页面管理有一个非常有趣的问题。

这个问题是这样的:
– 如果我在URL的末尾调用一个带有“坏”参数的URL(无关紧要),如..../c< ,应用程序将按照Web中的说明显示正确的服务器错误页面的.config;
– 如果我将URL更改为更讨厌的URL,例如.../<c (看起来更像HTML标记,浏览器中不再显示服务器错误页面,而不是那个,我得到了一个普通的YSOD, An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.了一条An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.消息An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.

据ELMAH称,两个请求都以400状态代码结束,消息为:
– 对于第一个: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<). at System.Web.HttpRequest.ValidateInputIfRequiredByConfig() at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context) System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<). at System.Web.HttpRequest.ValidateInputIfRequiredByConfig() at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
– 对于第二个: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<). at System.Web.HttpRequest.ValidateInputIfRequiredByConfig() at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context) System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<). at System.Web.HttpRequest.ValidateInputIfRequiredByConfig() at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)

因此,两个错误都是相同的,状态代码是相同的,但对于其中一个错误,自定义错误页面不会显示。 我也在调试模式下访问了global.asax并检查了protected void Application_Error(object sender, EventArgs e)Server.GetLastError() ,并且两次错误都是相同的,没有什么不同。

在web.config中,这是我的标记的样子:

请有人告诉我为什么这两种情况的行为不同?

非常感谢您的宝贵时间。

关于IIS 7+中的error handling,有很多错误信息和/或过时的解决方案。 要了解的主要内容是: –

  • .NET 4.0对ASP.NET的请求validation进行了重大更改。
  • IIS 7+引入了一种处理自定义错误页面的新方法。

大多数人都在使用涉及所有customErrors hodge-podge解决方案, httpErrorsApplication_Error处理程序,并经常在httpRuntime属性上设置requestValidationMode="2.0"和/或完全禁用请求validation! 这使得使用其他人的解决方案变得非常困难,因为任何和所有这些都会影响行为。 我快速搜索了一下,我找到了几个没有接受答案的半复制品,可能是因为这个原因。

这两个错误给您带来不同行为的原因是它们出现在请求管道的不同阶段web.configcustomErrors节点与应用程序内部的错误交互,而请求validation发生在应用程序“ 外部 ”。 IIS 到达您的应用程序代码之前拒绝该危险请求,因此您的customErrors替换不会发生。

那么我们如何解决这个问题呢?

理想情况下,您需要一个尽可能少的移动部件的解决方案。 IIS7为我们提供了一种在IIS级别而不是在应用程序级别指定错误页面替换的新方法 – httpErrors节点。 这让我们可以在一个地方捕获所有错误: –

  ...  ...        ...  ...  

如果你关心SEO(你应该!),你仍然需要确保你的控制器/页面设置一个合适的状态代码: –

 this.Response.StatusCode = 500; // etc. 

您应该完全删除customErrors节点。 它通常用于向后兼容。 您还应确保httpRuntime节点上设置requestValidationMode

这应该可以捕获大多数错误(显然,解析web.config时出现错误!)

相关: – ASP.NET MVC自定义错误

MSDN文档: – http://www.iis.net/configreference/system.webserver/httperrors

注意:在您的情况下,如果要在httpErrors节点上设置defaultPath ,则会因ApplicationHost.config设置而导致锁定违规。 你可以像我一样做,只为你关心的错误代码单独设置path ,或者你可以看看解锁节点: –

我的直觉是,在Azure App Service / Azure Web Sites等低控制环境中,它比它的价值更大。 您也可以设置各个状态代码的路径。

我已经在github上提供了一个完整的工作示例,使用httpErrors来自定义错误页面 。 您也可以在azure色的网站上看到它 。