捕获Global.asax中的错误

时间:2012-04-08 09:36:48

标签: c# asp.net error-handling

我的Global.aspx中有以下内容用于处理错误:

void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    if (exception != null)
    {
        //Log
        if (HttpContext.Current.Server != null)
        {
           HttpContext.Current.Server.Transfer("/siteerror.aspx");
        }
    }
}

这在很大程度上起作用,但有时不会进入Server.Transfer。由于某种原因,HttpContext.Current.Server为null。我想出了这种情况发生的地方:用户控件和业务逻辑类中发生错误。我在这里错过了什么吗?

由于

3 个答案:

答案 0 :(得分:2)

Application_Error块可以在应用程序生命周期之间的任何时间捕获异常。

应用程序生命周期是会话生命周期的父级,因为您可以理解单个应用程序中可以有多个会话。

因此,在创建会话之前或会话到期之后,您可能会遇到HttpContext.Current null。

如果要编写特定于会话的错误重定向,则应始终检查当前HttpContext的Null。

您还可以使用Server.GetLastError来了解发生的错误详细信息,并通过web.config中的CustomError标记重定向错误页面

请参阅以下链接

http://weblogs.asp.net/scottgu/archive/2006/08/12/Tip_2F00_Trick_3A00_-Show-Detailed-Error-Messages-to-Developers.aspx

答案 1 :(得分:1)

应用程序错误可以随时发生 - 包括没有连接时。

例如,如果后台线程正在处理并导致异常。

答案 2 :(得分:0)

enter image description here 阻止级别

这是应用程序中最精细的异常处理级别。我们非常熟悉try-catch块,可以将它们包装在一组代码上,如果发生异常,则它将处理此异常。异常处理块是这样的。

try
{
    throw new InsufficientMemoryException();
}
catch (Exception ex)
{
    throw new Exception("");
}
catch
{
    throw;
}

由于这不是基本的异常处理文章,因此我们不会深入研究该示例。

页面级别

我们可以在页面级别实现异常处理机制。好处是我们不需要将所有代码都包装在try-catch-finally块中;我们可以说,这是集中页面的异常处理机制。 无论异常发生在哪里,它将通过以下代码捕获。

void Page_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
}

要确定异常类型,我们需要使用Server类的GetLastError()函数,该函数将返回异常类型对象,并且通过检查该对象,我们可以做出进一步的决定,是在此页面中处理异常还是将其抛出到更高的水平。如果更高的级别,那么更高的级别呢?

应用程序级别

是的,这是异常处理机制的顶层。如果我们在Global.asax页面中实现它。我们都熟悉Global.asax页面,该页面主要处理与Global(应用程序)和会话相关的对象。如果我们在此页面中实现Application_Error()事件,则所有未处理的异常都将在此处堆叠,我们可以对错误做出最高决策。我们将忽略它还是将其记录或通过邮件发送。这是Global.asax页面中Application_Error()的实现。

protected void Application_Error(object sender, EventArgs e)
{
    //Catch Exception in Central place
    Exception exceptionObject = Server.GetLastError();
}

异常检测机制与页面级异常处理机制非常相似。我们正在使用Server类的GetLastError()函数,该函数将返回一个异常类型对象。现在,我们有责任进一步研究异常类型及其可能的解决方案。

好的,我们已经看到了ASP.NET应用程序中异常处理机制的三个级别。现在,显而易见的问题是,我们是否应该在单个应用程序中实现所有这些级别?为什么不?他们可以在同一应用程序中和平地调整自己,而且他们像团队一样工作。如果一个未能处理异常,则另一个尝试。如果再次失败,则它的上级权限将尝试执行此操作。

好的,下一个问题是底层是否能够解决该异常?会更高吗?不,如果较低的级别能够处理异常,那么它将不会冒泡(调用)其较高的级别。让我们澄清一下概念。

在一个ASP.NET页面中,我编写了这段代码。

try
{
  throw new DivideByZeroException();
}
catch (DivideByZeroException ex)
{
}
catch
{
    throw;
}

在我们从try块引发DivideByZero异常的地方,然后通过传递适当的Exception对象类型来捕获它。因此catch块可以处理异常。现在,使情况变得更加复杂。在此页面中,我们将在页面级别保留以下代码以进行全局异常处理。

void Page_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
}

我们将看到代码在异常处理时不会执行。由于本机try-catch块足以处理异常,因此无需调用其上级机制,并且出于相同的原因,如果存在的话,将跳过应用程序级异常机制。 很好,到目前为止,我们已经了解了异常机制的级别并阐明了其一些概念。现在,我们将在一个示例应用程序中实现所有这些级别,并且我们将实现我们的目标。让我们逐步进行。

第1步:在块级创建异常并使用try-catch换行

该步骤非常简单,我们已经做了很多次。在一个try块中,我们引发一个InsufficientMemoryException,并且假设该try块将引发“ DivideByZeroException”,如果我们的假设正确,则可以处理该异常,否则将其抛出更高的级别。

try
{
    throw new InsufficientMemoryException();
}
catch (DivideByZeroException ex)
{
   //show Message
}
catch
{
    throw;
}

更高级别的机制在哪里?页面级别。我们将在下一步中实现它。

第2步:在页面级实施异常处理机制

这是下一级别的异常处理。我们已经实现了一个Page_Error()事件,该事件可以捕获此页面中所有未处理的异常。现在,我们期望该页面仅引发ObjectDisposeException,并且乐观的说,我们保留了仅处理此类异常的机制。 (这是一个非常愚蠢的实现,我们不应该这样做。)无论如何,如果异常是任何其他类型,那么我们将其抛出更高的处理机制。

void Page_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    if (ex is ObjectDisposedException)
    {
       //Log this Exception
    }
    else
    throw new HttpUnhandledException("Unhandle Exception", ex);
}

下一个更高的权限是应用程序级异常处理机制。

第3步:在Global.asax页面中实现Application_Error()

protected void Application_Error(object sender, EventArgs e)
{
    //Catch Exception in Global place
    Exception exceptionObject = Server.GetLastError();
    try
    {
        if (exceptionObject != null)
        {
            if (exceptionObject.InnerException != null)
            {
                exceptionObject = exceptionObject.InnerException;
            }
            switch (exceptionObject.GetType().ToString())
            {
                case "System.Threading.ThreadAbortException":
                HttpContext.Current.Server.ClearError();
                break;
                default:
                LogException(exceptionObject);//Custom method to log error
                break;
            }
        }
    }
    catch { }//Avoiding further exception from exception handling
}

LogException()函数是一个存根,用于通过超出我们的核心解释来实现更多内容。在这里。

public static void LogException(Exception ex)
{
    //Log my Exception
}