0

我正在用 C# 编写一个 ASP.NET 应用程序,并且我正在处理可能从另一个文件中抛出的异常。我有一个我编写的 C# 类文件,其中包含执行 SQL 命令的方法,并且我想防止在我的应用程序投入生产后引发可能的异常。

这是我写的 SQL 方法,我故意在(来自 SqlData.cs)中抛出错误:

public SqlConnection openConnection()
{
        //Create an SQL connection
        SqlConnection myConnection = new SqlConnection("My intentionally incorrect connection string");

        //Open the connection
        try
        {
            myConnection.Open();
        }
        catch (SqlException myAppEx)
        {
            throw new ApplicationException("There was an error opening the SQL database connection", myAppEx);
        }

        return myConnection;
    }

我使用以下代码行从我的 Default.aspx.cs 文件中调用此方法:

try
{
    //The ReadDT method calls openConnection() in itself
    dt = sqlData.ReadDT(query);
}
catch (ApplicationException exc)
{
    throw exc;
}

我正在尝试实现页面级异常处理,如果在当前页面上引发异常,则应该调用 Page_Error 方法,如此所述。这就是为什么我捕获从我的 SqlData.cs 类文件中抛出的异常,然后重新抛出异常,以便服务器可以看到这个异常。因此,Server.GetLastError()不会返回null

正如这里实现的那样,我有一个单独的错误页面,显示有关异常的所有信息。我的 Page_Error 方法如下:

private void Page_Error(object sender, EventArgs e)
{
    Server.Transfer("ErrorPage.aspx?handler=Page_Error%20-%20Default.aspx", true);
}

从这里用户被重定向到我的 ErrorPage.aspx 并且SqlException最初抛出的被完美地显示。

问题 - 当我从 SqlData.cs 捕获异常并重新抛出异常时,UnhandledException会引发 an 。如果我没有在 ReadDT 方法调用周围放置一个 try catch 块,则会UnhandledException从我的 SqlData.cs 文件中引发同样的问题。

代码跟踪:

  1. throw new ApplicationException("There was an error opening the SQL database connection", myAppEx);(这工作正常)
  2. 然后捕获并重新抛出异常(UnhandledException发生)
  3. Page_Error方法按原样调用,一切正常执行!

我希望我已经清楚地回答了自己,我已经对异常和我的特定问题进行了大量研究,但我没有成功找到答案。

谢谢,埃里克

4

2 回答 2

0

在 ASP.NET 中,应用程序抛出的未处理异常将在调用 Page 或全局错误处理程序之前包装在HttpUnhandledException中。您需要查看它的InnerException属性以获取原始异常。

通常,除非您正在增加价值(例如,有关异常上下文的附加数据),否则您不应该像您正在做的那样费心包装和重新抛出异常。只需让它们传播到最终处理它们的任何地方(在您的情况下为 Page_Error,尽管您可能会考虑在 global.asax.cs 中使用 Application_Error,以避免在每个页面上重复此错误处理代码)。

于 2013-07-05T16:03:00.807 回答
0

所以我想出了通过代码级异常处理的错误处理组合,并将用户重定向到错误页面,然后使用 ELMAH 记录错误,以解决我的问题。

我现在直接在我的 SqlData 类文件中处理所有异常,以获取最少但最有效的代码。我的 SqlData 类文件中有一个全局变量HttpResponse response,每次从 ASP.NET 应用程序中创建该类的新实例时都会填充该变量。所以从我的 Main.aspx.cs 文件中我有类似的东西:

private SQLData data;

protected void Page_Load(object sender, EventArgs e)
{
    data = new SQLData(Response);
    ...
}

如果我这样做,我可以response.Redirect()从我的类文件中调用 a 将用户发送到我的错误页面,我会在查询字符串中传递异常错误消息和异常类型,然后在我的错误中将其打印给用户页。这允许我只向用户显示非敏感信息。因此,异常已得到处理,ELMAH 已记录所有细节!

//Create an SQL connection
SqlConnection myConnection = new SqlConnection("MyConnString");

//Open the connection
try
{
    myConnection.Open();
}
catch (Exception ex)
{
    //Manually log the exception in ELMAH
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
    //Redirect the user to the error page
    response.Redirect("ErrorPage.aspx?ErrorMessage=" + ex.Message + "&ErrorType=SQLException", true);
}

return myConnection;

elamh.axd然后,仅当您是管理员时,我的错误页面底部才会显示指向该页面的链接。在此页面中,您可以查看堆栈跟踪和其他敏感信息。

您可以在本页底部找到有关 ELMAH 的信息以及在 ASP.NET 应用程序中设置 ELMAH。这很容易做到,而且是一个非常强大的工具。

干杯,埃里克

于 2013-07-11T13:52:23.937 回答