如何正确设置 ASP.NET web.config 以在边缘情况下显示特定于应用程序、安全且用户友好的 asp.net 错误消息

问题描述

在我们的 asp.net 网页 (.net 4.7.2) 中,我们使用自定义异常呈现逻辑,通过以下方式为 global.asax.cs 中的用户创建特定错误页面

Application_Error(object sender,EventArgs e)

这很好用。但是,有一些 ASP.NET 错误永远不会触发 Application_Error 事件。
对于这些错误,我们通过 customErrors 元素在 web.config 中明确设置了一个错误页面。这看起来像这样:

<customErrors mode="On" defaultRedirect="~/CustomErrors/FatalError.aspx" redirectMode="ResponseRewrite"  />

问题
以上在大多数情况下都可以正常工作。但是,有一些 asp.net 错误不会被 Application_Error 事件处理,并且还会导致 FatalError.aspx 抛出异常,即使其中没​​有 asp 代码。这种错误一个很好的例子是,当您在浏览器中输入以下 reserved address 时:

https://[yourWebsite]/com1

这会破坏基于 .aspx 的错误页面,并显示以下错误消息 (Http-Status-Code 500):

处理您的请求时发生异常。此外,在执行自定义错误页面时发生了另一个异常 第一个例外。请求已终止。

即使设置一个里面绝对没有 asp 代码的 aspx 文件,也会导致这个错误。如果将 defaultRedirect 属性配置为不存在的资源,也会发生同样的情况!如果在 error-element 下定义了明确的 customErrors-elements,它也没有任何区别,这些元素根据明确的 http statusCode 定义重定向资源。

redirectMode 元素的 customErrors 设置为 ResponseRedirect 时,基于 aspx 的错误处理程序工作正常。 但是,这不是选项,因为我们的客户不想看到重定向

作为一种解决方法,我们可以尝试使用静态 html 文件。但是,在这种情况下,asp.net 将没有正确内容类型的响应发送回浏览器,并且 HTML 页面呈现为文本。
互联网上有很多帖子指出这是一个错误。但是,建议的解决方案始终是使用 .aspx 文件,或使用 global.asax.cs 中的 Application_Error 事件在代码中手动设置内容类型。但是,在如上所述的这种情况下,这两种变体都不可能(每个 aspx 文件都失败,Application_Error 永远不会被调用)。

问题
我们如何配置可靠的错误处理,它从不显示任何特定于 ASP.NET 的错误信息,而是显示特定于应用程序的错误信息,即使存在本文所述的边缘情况。
请注意,问题不在于如何避免保留资源名称错误。这只是一个例子,可能还有更多其他情况,其中发生了 asp.net 错误,这些错误永远不会到达 Application_Error 事件并导致基于 aspx 的错误文件关闭。我们的目标实际上是拥有一种机制来呈现应用程序标记错误消息,而不是完全可靠的 asp.net 错误消息。

此外,我们还使用 webServer 部分中的 httpErrors 元素作为辅助节点来更改不是源自 asp.net 而是源自 IIS 本身的错误。但是,我们没有观察到对上述问题的任何依赖性,因此,我没有在正文中提及。

解决方法

错误不是从 IIS 传递的 Application_Error 传递。您可以在此会话的 web.config 上配置此错误。

这是处理未找到页面的示例,witch 表示大多数未通过 Application_Error 的错误。

403 错误是 Forbidder 错误。

<system.webServer>
    <httpErrors>
      <remove statusCode="404" subStatusCode="-1" />
      <remove statusCode="403" subStatusCode="-1" />      
      <error statusCode="404" prefixLanguageFilePath="" path="/PageNotFound.aspx" responseMode="ExecuteURL" />
      <error statusCode="403" prefixLanguageFilePath="" path="/PageNotFound.aspx" responseMode="ExecuteURL" />        
     </httpErrors>
</system.webServer>

我如何在 Application_Error 上使用 global.asax

void Application_Error(object sender,EventArgs e)
{
    // log the last error
    Exception LastOneError = Server.GetLastError();

    string cTheFile = HttpContext.Current.Request.Path;

    if (!cTheFile.EndsWith("PageNotFound.aspx",StringComparison.InvariantCultureIgnoreCase))
    {
        // check for this above -> fPageNotExist
        // reference: https://stackoverflow.com/a/14032497/159270
        if(fPageNotExist)
            Response.Redirect("~/PageNotFound.aspx");
        else
            Server.Transfer("~/PageNotFound.aspx");
    }
}

在你写的时候也使用

<customErrors mode="On" defaultRedirect="~/error.aspx" redirectMode="ResponseRewrite">

COM1-9、LPT1-9、AUX、PRT、NUL、CON 文件是 pseudofiles 可以避免在 web.config 上使用此选项 - 它用于 IIS

<configuration>
  <system.web>
    <httpRuntime relaxedUrlToFileSystemMapping="true"   ....other settings.... />

   </system.web>
</configuration>

通过设置此选项,您将在 asp.net 下再次获取此文件 - 但我不会推荐这样做,因为此请求不是来自您系统的常规使用,也可能不是not be protected well 如果您将其设为 true。

网络表单和 viewStateKey

​​>

对于 web forms,我检查错误的另一点是关于 viewStateKey 后值 - 有关更多详细信息,您可以阅读此问答:

CryptographicException: Padding is invalid and cannot be removed and Validation of viewstate MAC failed

,
<system.web>
<customErrors mode=”On” redirectMode=”ResponseRewrite”>
<error statusCode=”500″ redirect=”~/errorpages/500.aspx” />
</customErrors>
</system.web>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...