ASP.NET OnError没有捕获ConfigurationErrorsException

时间:2014-08-14 02:57:40

标签: c# asp.net .net

从链接到ASP.NET站点的类库中抛出了ConfigurationErrorsException。该站点使用Global.ASAX错误事件和覆盖ASP.NET页面OnError()保护方法记录所有错误。它们都没有在抛出时处理ConfigurationErrorsException。

当类库中的异常类型从ConfigurationErrorsException更改为ApplicationException时,页面OnError方法处理异常。

为什么抛出的Exception类型会改变ASP.NET处理异常的方式?如果您希望在ASP.NET OnError和/或Global.asax页面中处理所有错误,那么可以安全地抛出异常的错误事件?

以下代码演示了我所描述的内容。当您单击“应用程序例外”按钮时,OnError中的断点将被点击,而当您单击“配置例外”按钮时则不会点击...

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="OnErrorTest.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:Button ID="btnInvalidOpEx" runat="server" Text="Invalid OP Exception" OnClick="btnInvalidOpEx_OnClick" />
    <asp:Button ID="btnAppEx" runat="server" Text="Application Exception" OnClick="bthnAppEx_OnClick" />
    <asp:Button ID="btnConfigEx" runat="server" Text="Configurations Exception" OnClick="btnConfigEx_OnClick" />    
    </div>
    </form>
</body>
</html>

背后的代码

using System;
using System.Configuration;
using System.Web;

namespace OnErrorTest
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected override void OnError(EventArgs e)
        {
            HttpContext ctx = HttpContext.Current;

            System.Exception exception = ctx.Server.GetLastError();
        }

        protected void bthnAppEx_OnClick(object sender, EventArgs e)
        {
            throw new ApplicationException("Application Error");
        }

        protected void btnConfigEx_OnClick(object sender, EventArgs e)
        {
            throw new ConfigurationErrorsException("Configurations Error");
        }

        protected void btnInvalidOpEx_OnClick(object sender, EventArgs e)
        {
            throw new InvalidOperationException("Configurations Error");
        }
    }
}

编辑:有人提出ConfigurationErrorsException是一个系统异常,它意味着由.NET Framework而不是应用程序抛出。它确实派生自SystemException,但InvalidOperationException也是如此。 OnError捕获InvalidOperationException

结论:除非您的意图是不在ASP.NET页面的OnError方法或全局异常处理程序中处理它,否则不要抛出从ConfigurationException派生的任何内容。我已经测试了MVC,没有Controller.OnException没有对ConfigurationException的这种歧视。

2 个答案:

答案 0 :(得分:1)

我偷看了source code for ProcessRequestMain。此方法中有一个try...catch块,它捕获任何ConfigurationException并再次抛出它(查看第4680行)。所有其他例外情况都会移至HandleError方法,该方法会调用OnError。 (ThreadAbortException也是单独处理的,这不是你关注的问题。)

这就是为什么您无法使用ConfigurationException方法或ConfigurationErrorsException事件捕获ConfigurationException(和OnError继承自Error)的原因ASP.NET页面。

答案 1 :(得分:0)

我认为这是因为配置错误实际上会阻止应用程序正常运行,而且根据文档,配置错误也不是由我们抛出,而是由框架本身抛出。由于大多数配置导致应用程序无法运行,因此无法使用日志记录工具捕获配置错误,因为它无法配置环境以在发生该错误时运行日志记录工具。