[ZT]ASP.NET的錯誤處理機制

通常情况下,我们在写ASP.NET程序的时候,会经常遇到如何处理错误处理机制的问题.可以说一个良好的错误处理机制是衡量Web应用程序好坏的一个重要标准.

下面将介绍四中错误处理机制:
1.使用Web.Config的<customErrors>配置项

例子:
<?xml version="1.0"?>
    
<configuration>
        
<system.web>
            
<customErrors mode="On" defaultRedirect="GenericErrorPage.htm">  //指定了开启错误处理机制,并指定到固定页面处理错误提示
                
<error statusCode="403" redirect="Error403.htm" /> 
                
<error statusCode="404" redirect="Error404.htm" />  
            
</customErrors>
        
</system.web>
    
</configuration>


2.使用Global.asax中的Application_Error事件处理方法
在这些事件当中,有一个属于Application范畴的与错误相关的事件——Error,而对应的事件处理方法就是Application_Error了。顾名思义,这个事件处理方法在应用程序级别错误发生的时候就会被调用,因此你可以在这个方法中添加代码来对错误进行处理,如下所示:
protected void Application_Error(object sender, EventArgs e) {
    Exception objErr 
= Server.GetLastError().GetBaseException();
    Response.Write(
"Error:" + objErr.Message);
    Server.ClearError();
}

以上这两种错误处理方法都可以说是全局性的,一个源自应用程序配置文件,一个则是必须放在应用程序根目录下的Global.asax文件的事件处理方法。与全局相对的就是局部,所以我们很自然的就会想:有没有应用于局部——某个页面的错误处理机制呢?答案是“有的”,而且还有两种————使用ErrorPage属性以及使用Page_Error事件处理方法

3.使用ErrorPage属性处理错误机制
你几乎可以在任何时候设置ErrorPage属性,从而确定页面发生错误的时候会重定向至哪个页面
<script language="C#" runat="server">
    
protected void Page_Load(object sender, EventArgs e) {
        
this.ErrorPage = "ErrorPage.htm";
        
    }
   
</script>

4.使用Page_Error事件处理方法处理错误机制
与Application_Error事件处理方法是很类似的,只不过被触发的时机不同而已。
protected void Page_Error(object sender, EventArgs e) {
    Exception objErr 
= Server.GetLastError().GetBaseException();
    Response.Write(
"Error:" + objErr.Message);
    Server.ClearError(); 
//同样要注意这句代码的使用
}
    

       至此,四种错误处理机制已经悉数登场,是时候给它们排个名次了。根据优先级从高到低排序:Page_Error事件处理方法 > ErrorPage属性 > Application_Error事件处理方法 >  <customErrors>配置项。虽然排序是这样,但是这个排序之间又有微妙的关系。首先,要让ErrorPage属性能够发挥作用,<customErrors>配置项中的mode属性必须设为"On";其次,虽然Page_Error事件处理方法排在最前面,但是,如果少掉了Server.ClearError()方法的话,仍然会引发优先级较低的错误处理,也就是说ErrorPage属性等错误处理机制仍然会发挥作用,这样就得不到你想要的结果了。这种情况对于Application_Error事件处理方法也是如此。顺序是排好了,但是顺序却不是最重要的问题,甚至可以说是没有太多意义的问题,因为在很多情况下,你可能并不会混合使用这四种处理机制。我想,最重要的问题还是在如何选用这些错误处理机制上。对于这个问题,希望有经验的朋友能够谈谈看法。


对Web应用程序来说,发生不可预知的错误和异常在所难免,我们必须为Web程序提供错误处理机制。当错误发生时,我们必须做好两件事情:一是将错误信息记录日志,发邮件通知网站维护人员,方便技术人员对错误进行跟踪处理;二是以友好的方式提示最终用户页面发生了错误,而不能将未处理的错误信息显示给用户。

     让我们想想,ASP.NET为我们提供了几种错误处理机制?如果同时使用他们是不是有一定的优先级?.NET提供了四种错误处理机制,它们有一定的优先级顺序:Page_Error事件>ErrorPage属性>Application_Error事件> <customErrors>配置项。下面分别介绍这四种错误处理机制的用法。

    1.Page_Error事件
     Page_Error 事件提供一种捕获在页级别出现的错误的方法。您可以只是显示错误信息(正如下面的示例代码所示),也可以记录事件或执行某个其他操作。
    private void Page_Load(object sender, System.EventArgs e)
    {
        // Put user code to initialize the page here
        throw new Exception("Page Error!");
    }

    protected void Page_Error(object sender, EventArgs e)
    {
        Exception objErr = Server.GetLastError().GetBaseException();
        Response.Write("Error:" + objErr.Message);
        Server.ClearError(); //同样要注意这句代码的使用
    }    备注:此示例在浏览器中显示详细的错误信息,提供此示例只是为了进行说明。向应用程序的最终用户显示详细信息一定要小心。更适当的做法是向用户显示一条消息,告知已发生错误,然后将具体的错误详细信息记录在日志中。

    2.ErrorPage属性
     你几乎可以在页面任何时候设置ErrorPage属性,从而确定页面发生错误的时候会重定向至哪个页面。要让ErrorPage属性能够发挥作用,<customErrors>配置项中的mode属性必须设为"On"。
    this.ErrorPage = "~/ErrorHandling/PageError.html";
    如果Page_Error和ErrorPage都存在,当抛出Exception时,页面执行顺序是怎样的呢?页面会先执行Page_Error事件处理函数,如果Page_Error()事件中调用函数Server.ClearError()清除异常信息,则不会跳转到ErrorPage属性指定页面;如果没有调用Server.ClearError(),Exception信息会继续向上抛,页面会跳转到ErrorPage指定页面。这也就证明了优先级顺序:Page_Error事件>ErrorPage属性。

     3.Application_Error事件
      与Page_Error 事件相类似,您可使用Application_Error事件捕获发生在应用程序中的错误。由于事件发生在整个应用程序范围内,因此您可记录应用程序的错误信息或处理其他可能发生的应用程序级别的错误。在Global.asax文件中添加如下代码就OK了。
protected void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError().GetBaseException();
        //实际应用中这里可以将Exception信息记Log或是保存到数据库中
        //还可以将错误发邮件给网站维护人员
        Response.Write("Error:" + ex.Message);
        //清除Exception,避免继续传递给上一级处理
        //这里上级就是<CustomerErrors>配置节了
        Server.ClearError();
    }
      4.<customErrors>配置项
       配置文件web.config中的<customErrors> 配置节,可将重定向页指定为默认的错误页defaultRedirect或者根据引发的 HTTP 错误代码指定特定页。如果发生在应用程序以前的任一级别都未捕获到的错误,则显示这个自定义页。
<customErrors mode="On" defaultRedirect="~/ErrorHandling/ApplicationError.html">
      <error statusCode="404" redirect="~/ErrorHandling/404.html" />
</customErrors>   
       同样,如果Application_Error和<customerErrors>同时存在,也存在执行顺序的问题。因为优先级Application_Error事件> <customErrors>配置项,所以发生应用程序级错误时,优先执行Application_Error事件中的代码,如果Application_Error事件中调用了Server.ClearError()函数,<customerErrors>配置节中的defaultRedirect不起作用,因为Exception已经被清除;如果Application_Error事件中没用调用了Server.ClearError()函数,错误页会重新定位到defaultRedict指定的URL页面,为用户显示友好出错信息。

       通过对.NET提供的以上四种错误处理机制的分析,我们可以把它们从不同的角度分类,便于我们理解和使用。
      1.从功能上分类:用于异常处理(Handling exceptions)是Page_Error事件和Application_Error事件;用户错误页面重定向(Redirecting the user to an error page)的是 ErrorPage属性 和 <customErrors>配置项。
      2.从错误处理的范围分类:用于页面级(Page level)错误处理的是Page_Error事件 和 ErrorPage属性;用于应用程序级(Application level)错误处理的是Application_Error事件 和 <customErrors>配置项。

原文地址:https://www.cnblogs.com/godwar/p/1287775.html