【问题标题】:Exception Handling in ASP.NET (C#) from a separate class file来自单独类文件的 ASP.NET (C#) 中的异常处理
【发布时间】:2013-07-03 17:36:46
【问题描述】:

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

这是我写的SQL方法,我故意在(From 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 方法,如引用 here。这就是为什么我捕获从我的 SqlData.cs 类文件中抛出的异常,然后重新抛出异常,以便服务器可以看到这个异常。因此,Server.GetLastError() 不会返回 null

作为实现here,我有一个单独的错误页面,显示有关异常的所有信息。我的 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。如果我不在 ReadDT 方法调用周围放置 try catch 块,则会从我的 SqlData.cs 文件中引发相同的 UnhandledException

代码跟踪:

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

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

谢谢, 埃里克

【问题讨论】:

  • 所以您的总体目标是确保在发生异常时将用户重定向到错误页面?
  • 全局文件中的Application_Exception 怎么样?
  • Listen to Shekhar... global.aspx 文件中有一个全局异常处理程序或其他任何名称...您可以使用它(我过去有)重定向到自定义错误页面...
  • @Arran - 当异常发生时,用户被引导到错误页面,但在不应该出现的情况下,UnhandledException 被抛出。 @Shekhar 和 @MartinMilan - 我之前使用过 Application_Exception 方法,但在应用程序到达 Application_Exception 方法之前发生了 UnhandledException 异常。

标签: c# asp.net sql exception-handling


【解决方案1】:

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

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

【讨论】:

  • 我明白这一点,但我不知道如何阻止它在到达 Page_ErrorApplication_Error 处理程序之前抛出 UnhandledException
  • 如果您想阻止错误传播,您可以致电Server.ClearError(),但我不明白您为什么要这样做。 Server.Transfer 没有按预期工作吗?
  • 我在Default.aspx.cs 文件中捕获错误并将其重新抛出的全部原因是因为需要在我的服务器文件中而不是在我的SqlData.cs 文件中抛出异常,否则@987654328 @ 将是 null。就 ASP 应用程序而言,当它出现在我的类文件中时,没有引发异常。
  • "就 ASP 应用程序而言,当它出现在我的类文件中时,没有抛出异常。" - 我不相信这是真的,我建议你设置一个小样本来尝试重现它。
  • 经过进一步研究,我发现:当抛出更高的异常时,不要:抛出新的 ApplicationException(e) 做:抛出
【解决方案2】:

所以我想出了通过代码级异常处理的错误处理组合,并将用户重定向到错误页面,然后使用 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() 以将用户发送到我的错误页面,我将异常错误消息和异常类型传递到查询字符串中,然后我将其打印出来在我的错误页面中给用户。这允许我只向用户显示非敏感信息。因此,异常已得到处理,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 页面的链接,前提是您是管理员。在此页面中,您可以查看堆栈跟踪和其他敏感信息。

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

干杯, 埃里克

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    相关资源
    最近更新 更多