从链接到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的这种歧视。
答案 0 :(得分:1)
我偷看了source code for ProcessRequestMain
。此方法中有一个try...catch
块,它捕获任何ConfigurationException
并再次抛出它(查看第4680行)。所有其他例外情况都会移至HandleError
方法,该方法会调用OnError
。 (ThreadAbortException
也是单独处理的,这不是你关注的问题。)
这就是为什么您无法使用ConfigurationException
方法或ConfigurationErrorsException
事件捕获ConfigurationException
(和OnError
继承自Error
)的原因ASP.NET页面。
答案 1 :(得分:0)
我认为这是因为配置错误实际上会阻止应用程序正常运行,而且根据文档,配置错误也不是由我们抛出,而是由框架本身抛出。由于大多数配置导致应用程序无法运行,因此无法使用日志记录工具捕获配置错误,因为它无法配置环境以在发生该错误时运行日志记录工具。