显示自定义错误页 (VB)

作者 :Scott Mitchell

ASP.NET Web 应用程序中发生运行时错误时,用户会看到什么? 答案取决于网站的 <customErrors> 配置方式。 默认情况下,用户会显示一个难看的黄色屏幕,表明发生了运行时错误。 本教程演示如何自定义这些设置,以显示符合网站外观的美观自定义错误页面。

简介

在完美的世界中,不会有运行时错误。 程序员会编写带有 bug 且具有可靠用户输入验证的代码,而数据库服务器和电子邮件服务器等外部资源永远不会脱机。 当然,在现实中,错误是不可避免的。 .NET Framework中的类通过引发异常来发出错误信号。 例如,调用 SqlConnection 对象的 Open 方法会建立与连接字符串指定的数据库的连接。 但是,如果数据库关闭或连接字符串中的凭据无效,则 Open 方法将 SqlException引发 。 可以使用块来处理 Try/Catch/Finally 异常。 如果块中的 Try 代码引发异常,则会将控件传输到相应的 catch 块,开发人员可在其中尝试从错误中恢复。 如果没有匹配的 catch 块,或者引发异常的代码不在 try 块中,则异常将扩展调用堆栈以搜索 Try/Catch/Finally 块。

如果异常一直冒泡到 ASP.NET 运行时而不进行处理,则会HttpApplication引发类的事件Error并显示配置的错误页。 默认情况下,ASP.NET 显示一个错误页,该错误页被亲切地称为 死亡 (YSOD) 。 YSOD 有两个版本:一个版本显示异常详细信息、堆栈跟踪和其他有助于开发人员调试应用程序的信息 (请参阅 图 1) ;另一个只是指出存在运行时错误 (请参阅 图 2) 。

异常详细信息 YSOD 对调试应用程序的开发人员非常有用,但向最终用户显示 YSOD 是俗气和不专业的。 相反,应将最终用户带到一个错误页面,该页面会使用更用户友好的散文来描述情况,从而保持网站的外观。 好消息是,创建此类自定义错误页面非常简单。 本教程首先介绍 ASP。NET 的不同错误页。 然后,它演示如何配置 Web 应用程序,以在遇到错误时向用户显示自定义错误页。

检查三种类型的错误页

当 ASP.NET 应用程序中出现未经处理的异常时,将显示以下三种类型的错误页之一:

  • “异常详细信息黄色死机屏幕”错误页,
  • 运行时错误死机黄屏错误页,或
  • 自定义错误页

开发人员最熟悉的错误页是异常详细信息 YSOD。 默认情况下,此页显示给在本地访问的用户,因此是在开发环境中测试站点时出错时看到的页面。 顾名思义,异常详细信息 YSOD 提供有关异常的详细信息 - 类型、消息和堆栈跟踪。 此外,如果异常是由 ASP.NET 页代码隐藏类中的代码引发的,并且已将应用程序配置为调试,则异常详细信息 YSOD 还将显示此代码行 (,并且上面和下方的几行代码) 。

图 1 显示了“异常详细信息 YSOD”页。 请注意浏览器地址窗口中的 URL: http://localhost:62275/Genre.aspx?ID=foo。 回想一下,页面 Genre.aspx 列出了特定流派的书评。 它要求 GenreId 通过查询字符串传递 (uniqueidentifier) 的值;例如,查看虚构评论的相应 URL 为 Genre.aspx?ID=7683ab5d-4589-4f03-a139-1c26044d0146。 如果通过查询字符串 ((如“foo”)传入非uniqueidentifier 值) 将引发异常。

注意

若要在可供下载的演示 Web 应用程序中重现此错误,可以直接访问 Genre.aspx?ID=foo 或单击 中的 Default.aspx“生成运行时错误”链接。

请注意 图 1 中提供的异常信息。 页面顶部显示异常消息“从字符串转换为 uniqueidentifier 时转换失败”。 还会列出异常 System.Data.SqlClient.SqlException的类型。 还有堆栈跟踪。

显示异常相关信息的屏幕截图。

图 1:异常详细信息 YSOD 包括有关异常的信息
(单击以查看全尺寸图像)

另一种类型的 YSOD 是运行时错误 YSOD, 如图 2 所示。 运行时错误 YSOD 通知访问者发生了运行时错误,但它不包括有关引发的异常的任何信息。 但是, (它确实提供了有关如何通过修改 Web.config 文件来查看错误详细信息的说明,这是使此类 YSOD 看起来不专业的一部分)

默认情况下,运行时错误 YSOD 显示给通过 http://www.yoursite.com) 远程访问 (的用户,如图 2 中浏览器地址栏中的 URL 所示: http://httpruntime.web703.discountasp.net/Genre.aspx?ID=foo。 存在两个不同的 YSOD 屏幕,因为开发人员有兴趣了解错误详细信息,但此类信息不应显示在实时网站上,因为它可能会向访问您的网站的任何人透露潜在的安全漏洞或其他敏感信息。

注意

如果你正在关注并将 DiscountASP.NET 用作 Web 主机,你可能会注意到,访问实时站点时不会显示运行时错误 YSOD。 这是因为 DiscountASP.NET 的服务器已配置为默认显示异常详细信息 YSOD。 好消息是,可以通过向文件添加 <customErrors> 节来 Web.config 替代此默认行为。 “配置显示哪个错误页”部分详细介绍了该 <customErrors> 部分。

显示运行时错误 YSOD 如何不包含任何错误详细信息的屏幕截图。

图 2:运行时错误 YSOD 不包含任何错误详细信息
(单击以查看全尺寸图像)

第三种类型的错误页是自定义错误页,它是你创建的网页。 自定义错误页的好处是可以完全控制向用户显示的信息以及页面的外观;自定义错误页可以使用与其他页面相同的母版页和样式。 “使用自定义错误页”部分介绍了如何创建自定义错误页并将其配置为在发生未经处理的异常时显示。 图 3 提供了此自定义错误页的潜行峰值。 如你所看到的,错误页面的外观和感觉比图 1 和图 2 中显示的任何一个死亡黄屏都更专业。

显示可以创建的自定义错误页的屏幕截图,以便提供更定制的外观。

图 3:自定义错误页提供更定制的外观
(单击以查看全尺寸图像)

花点时间检查 图 3 中浏览器的地址栏。 请注意,地址栏显示自定义错误页的 URL (/ErrorPages/Oops.aspx) 。 在图 1 和图 2 中,死亡的黄色屏幕显示在错误源自 () Genre.aspx 的同一页中。 自定义错误页通过 querystring 参数传递发生错误的页面的 aspxerrorpath URL。

配置显示哪个错误页

显示三个可能的错误页中的哪一个基于两个变量:

  • 部分中的配置信息 <customErrors> ,以及
  • 用户在本地还是远程访问站点。

中的 Web.config<customErrors>有两个属性,这些属性会影响显示的错误页:defaultRedirectmodedefaultRedirect 属性是可选项。 如果提供,则指定自定义错误页的 URL,并指示应显示自定义错误页,而不是运行时错误 YSOD。 属性 mode 是必需的,接受以下三个值之一: OnOffRemoteOnly。 这些值具有以下行为:

  • On - 指示向所有访问者显示自定义错误页或运行时错误 YSOD,无论这些访问者是本地访问者还是远程访问者。
  • Off - 指定向所有访问者显示异常详细信息 YSOD,无论这些访问者是本地访问者还是远程访问者。
  • RemoteOnly - 指示向远程访问者显示自定义错误页或运行时错误 YSOD,而向本地访问者显示异常详细信息 YSOD。

除非另行指定,否则 ASP.NET 就像将 mode 属性 RemoteOnly 设置为 并且未指定值一 defaultRedirect 样。 换句话说,默认行为是向本地访问者显示异常详细信息 YSOD,同时向远程访问者显示运行时错误 YSOD。 可以通过向 Web 应用程序的 添加节 <customErrors> 来替代此默认行为 Web.config file.

使用自定义错误页

每个 Web 应用程序都应有一个自定义错误页。 它为运行时错误 YSOD 提供了更专业外观的替代方法,它易于创建,将应用程序配置为使用自定义错误页只需几分钟。 第一步是创建自定义错误页。 我向书评应用程序添加了一个名为 ErrorPages 的新文件夹,并向其添加了名为 Oops.aspx的新 ASP.NET 页。 让页面使用与网站上的其他页面相同的母版页,以便它自动继承相同的外观。

显示 ErrorPages 文件夹的屏幕截图,该文件夹包含 Oops 点 s p x 文件。

图 4:创建自定义错误页

接下来,花几分钟时间创建错误页的内容。 我创建了一个相当简单的自定义错误页面,其中包含一条消息,指示发生了意外错误,并提供了一个返回网站主页的链接。

显示如何设计自己的自定义错误页的屏幕截图。

图 5:设计自定义错误页
(单击以查看全尺寸图像)

错误页完成后,将 Web 应用程序配置为使用自定义错误页代替运行时错误 YSOD。 这是通过在节的 属性中 <customErrors> 指定错误页的 URL 来实现的 defaultRedirect 。 将以下标记添加到应用程序的 Web.config 文件:

<configuration>
    ...

    <system.web>
        <customErrors mode="RemoteOnly"
                      defaultRedirect="~/ErrorPages/Oops.aspx" />

        ...
    </system.web>
</configuration>

上述标记将应用程序配置为向本地访问的用户显示异常详细信息 YSOD,同时对远程访问的用户使用自定义错误页 Oops.aspx。 若要在操作中了解这一点,请将网站部署到生产环境,然后使用无效的查询字符串值访问实时网站上的 Genre.aspx 页面。 应会看到自定义错误页 (参考 图 3) 。

若要验证自定义错误页是否仅显示给远程用户,请访问 Genre.aspx 来自开发环境的查询字符串无效的页面。 仍应看到异常详细信息 YSOD (参考 图 1) 。 此设置 RemoteOnly 可确保在生产环境中访问站点的用户访问自定义错误页,而在本地工作的开发人员继续查看异常的详细信息。

通知开发人员和日志记录错误详细信息

开发环境中发生的错误是由坐在她的计算机上的开发人员引起的。 她在异常详细信息 YSOD 中显示异常信息,并且她知道发生错误时她正在执行哪些步骤。 但是,当生产环境中发生错误时,除非访问该网站的最终用户花费时间报告错误,否则开发人员不知道发生了错误。 即使用户不法提醒开发团队发生错误,在不了解异常类型、消息和堆栈跟踪的情况下,也很难诊断错误的原因,更不用说修复错误了。

出于这些原因,将生产环境中的任何错误记录到某些持久性存储 ((如数据库) )并且开发人员收到此错误的警报至关重要。 自定义错误页似乎是执行此日志记录和通知的好位置。 遗憾的是,自定义错误页无权访问错误详细信息,因此不能用于记录此信息。 好消息是,有多种方法可以截获错误详细信息并记录它们,接下来的三个教程将更详细地探讨本主题。

对不同的 HTTP 错误状态使用不同的自定义错误页

当异常由 ASP.NET 页引发且未处理时,该异常将持续到显示配置的错误页 ASP.NET 运行时。 如果请求进入 ASP.NET 引擎,但由于某种原因而无法处理 (可能找不到请求的文件或已禁用该文件的读取权限)则 ASP.NET 引擎将引发 HttpException。 此异常与从 ASP.NET 页引发的异常一样,会浮升到运行时,从而导致显示相应的错误页。

对于生产中的 Web 应用程序而言,这意味着如果用户请求未找到的页面,则他们将看到自定义错误页。 图 6 显示了此类示例。 由于请求针对不存在的页面 (NoSuchPage.aspx) ,HttpException因此将引发 ,并显示自定义错误页, (在查询字符串参数) 记下aspxerrorpathNoSuchPage.aspx 的引用。

显示出现的配置错误页的屏幕截图。图 6:ASP.NET 运行时显示配置的错误页以响应无效请求
(单击以查看全尺寸图像)

默认情况下,所有类型的错误都会导致显示相同的自定义错误页。 但是,可以使用 节中的<customErrors>子元素为特定 HTTP 状态代码<error>指定不同的自定义错误页。 例如,若要在出现“找不到页面”错误(HTTP 状态代码为 404)时显示其他错误页,请更新 <customErrors> 节以包含以下标记:

<customErrors mode="RemoteOnly" defaultRedirect="~/ErrorPages/Oops.aspx">
    <error statusCode="404" redirect="~/ErrorPages/404.aspx" />
</customErrors>

进行此更改后,每当远程访问的用户请求不存在的 ASP.NET 资源时,他们将被重定向到 404.aspx 自定义错误页,而不是 Oops.aspx。 如图 7 所示,页面 404.aspx 可以包含比常规自定义错误页更具体的消息。

注意

请查看 404 错误页,再一次 获取有关创建有效 404 错误页的指导。

显示显示已加油消息的屏幕截图。图 7:自定义 404 错误页显示的目标性比 Oops.aspx
(单击以查看全尺寸图像)

因为你知道 404.aspx 只有在用户请求未找到的页面时才会访问该页面,因此可以增强此自定义错误页以包括帮助用户解决此特定类型的错误的功能。 例如,可以生成一个将已知错误 URL 映射到良好 URL 的数据库表,然后让 404.aspx 自定义错误页针对该表运行查询,并建议用户可能尝试访问的页面。

注意

仅当向 ASP.NET 引擎处理的资源发出请求时,才会显示自定义错误页。 正如我们在 IIS 与 ASP.NET 开发服务器之间的核心差异 教程中所述,Web 服务器本身可能会处理某些请求。 默认情况下,IIS Web 服务器在不调用 ASP.NET 引擎的情况下处理静态内容(如图像和 HTML 文件)的请求。 因此,如果用户请求不存在的图像文件,他们将返回 IIS 的默认 404 错误消息,而不是 ASP。NET 的已配置错误页。

总结

当 ASP.NET 应用程序中发生未经处理的异常时,将显示用户三个错误页之一:异常详细信息黄色死机屏幕;运行时错误黄色死机屏幕;或自定义错误页。 显示哪个错误页取决于应用程序的 <customErrors> 配置,以及用户是在本地访问还是远程访问。 默认行为是向本地访问者显示异常详细信息 YSOD,向远程访问者显示运行时错误 YSOD。

虽然运行时错误 YSOD 对访问站点的用户隐藏潜在的敏感信息,但它会破坏网站的外观,使应用程序看起来有错误。 更好的方法是使用自定义错误页,这需要创建和设计自定义错误页,并在节的 defaultRedirect 属性中<customErrors>指定其 URL。 对于不同的 HTTP 错误状态,甚至可以有多个自定义错误页。

自定义错误页是生产环境中网站的综合错误处理策略的第一步。 向开发人员发出错误警报并记录其详细信息也是重要的步骤。 接下来的三个教程将探讨错误通知和日志记录的技术。

编程快乐!

深入阅读

有关本教程中讨论的主题的详细信息,请参阅以下资源: