如何在抛出请求验证异常时显示自定义错误页面?

Ben*_*ter 12 asp.net custom-errors request-validation

我们为ASP.NET抛出的异常配置了以下自定义错误页面:

<customErrors mode="On" redirectMode="ResponseRewrite">
  <error statusCode="400" redirect="~/400.aspx"/>
  <error statusCode="404" redirect="~/404.aspx"/>
  <error statusCode="500" redirect="~/500.aspx"/>
</customErrors>
Run Code Online (Sandbox Code Playgroud)

设置redirectMode="ResponseRewrite"很重要,因为它确保URL不会更改(我相信ASP.NET执行Server.Transfer而不是Response.Redirect).

不幸的是,这不适用于请求验证错误.例如,如果我导航到/some/page/<script>ASP.NET的请求验证启动并且HttpException抛出了a,则启用自定义错误.但是,我没有显示自定义错误页面,而是收到以下消息:

'/'应用程序中的服务器错误.

运行时错误

描述:处理您的请求时发生异常.此外,执行第一个异常的自定义错误页面时发生另一个异常.请求已终止.

为什么ASP.NET无法在此方案中显示我的自定义错误页面?错误页面中没有代码,只有HTML,所以我知道错误页面本身不会抛出任何异常.

此外,如果我自己捕获错误Application_Error并发出Server.Transfer它工作正常,所以我很好奇ASP.NET正在做什么.

如果我们要自己解决这个问题,那么有更好的解决方案吗?

protected void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError() as HttpException;
    if (ex != null 
        && ex.Message.StartsWith("A potentially dangerous Request.Path value was detected from the client")
        && HttpContext.Current.IsCustomErrorEnabled)
    {
        Server.Transfer("400.aspx");
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 2

为了确保您不遗漏 web 应用程序中可能出现的任何错误代码,您可以添加默认错误页面:

<customErrors mode="On" defaultRedirect="Error.aspx" />
Run Code Online (Sandbox Code Playgroud)

如果您只想捕获 RequestValidationErrors 则可以在 global.asax 文件中处理它:

 void Application_Error(object sender, EventArgs e)
 {
    Exception ex = Server.GetLastError();
    if (ex is HttpRequestValidationException)
    {
        Server.ClearError();
        Response.Redirect("RequestValidationError.aspx", false);
    }
 }
Run Code Online (Sandbox Code Playgroud)