ASP.NET項目開發中的異常處理

From: http://www.cnblogs.com/yanyangtian/archive/2009/05/07/1451705.html

前言:異常的處理在項目開發中是很有必要的,異常的處理不僅僅只是try..catch..finally就完事了的。異常處理絕對可以稱開發中的重要組成部分。必須正確的面對異常,因爲即使是最能幹的開發人員,也要面對這個問題 ....


       我們不知道客戶是怎麼樣使用我們開發的軟件的,所以我們必須處理這樣的情況:如果系統不按照我們的設計時所想的運行,我們改怎麼辦?

       下面我們就來具體的介紹在ASP.NET項目開發中的異常的處理方式,希望看完後,大家可以回答上面的問題。

       本篇的話題如下:

       應用程序級別異常處理的錯誤處理
       頁面級別異常處理
       方法級別異常處理
       web.config文件異常處理配置
       健康監視(Health Monitoring)
       Enterprise Application Blocks異常處理模塊
 

 

      一.在應用程序級別的異常處理:
       相信大家對Application對象不陌生,而且在項目中添加過Global.asax文件。確實,ASP.NET在應用程序級別處理異常的代碼都是放在Global.asax的Application_Error事件處理下的:
 

void Application_Error(object sender, EventArgs e)
 
{
  
// Code that runs when an unhandled error occurs
 }
 

 

       我們可以在上面的事件處理的方法中捕獲所有的異常,而且還可以把異常記錄到日誌文件,並且同時發送Email告訴開發人員出現了什麼問題,如下

 

Exception error = Server.GetLastError().GetBaseException();
//在事件日誌中記錄異常
if (!EventLog.SourceExists("ApplicationException"))
{
        EventLog.CreateEventSource(
"ApplicationException""Application");
}


EventLog eventLog 
= new EventLog();
eventLog.Log 
= "Application";
eventLog.Source 
= "ApplicationException";
eventLog.WriteEntry(error.ToString(), EventLogEntryType.Error);

//發送Email給開發人員
MailMessage email = new MailMessage("[email protected]",
"[email protected]");
email.Body 
= error.ToString();
email.Subject 
= "An error occurred in the  Application";
SmtpClient smtpClient 
= new SmtpClient("127.0.0.1"25);
smtpClient.Send(email);
Response.Redirect(
"ErrorPage.aspx");




        當然,上面的代碼要正確的運行,我們海必須在Global.asax中加入相應的命名空間,而且在發送郵件的時候,上面的"127.0.0.1"要換爲我們自己的郵件服務器的地址:
 

<%@ Import Namespace="System.Diagnostics" %>
 
<%@ Import Namespace="System.Net.Mail" %>


 
 
       還有一點要注意的就是,ASP.NET運行時是以ASPNET賬戶運行的,這個賬戶的權限是有限的,如果我們想要使得上面的代碼可以運行,那麼就必須要給ASPNET賬戶訪問註冊表的權限。如果你不給權限,那麼上面的代碼就報錯。


       我們賦予ASPNET賬戶訪問在"HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog"節點以及字節點的權限。
       下面就講講如何配置權限:
       1.打開"運行"菜單
       2.輸入"regedit",然後確定
       3.導航到"HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog"節點。
       4.右擊這個節點,並且選擇"權限",此時就會彈出權限配置的窗口。
       5.點擊"添加",在彈出的窗口中點擊"高級",之後再點擊"查找",最後在下面的窗口找到"ASPNET"賬戶,確定。
       6.最後給予ASPNET賬戶讀的權限就OK了。

       上面的代碼,如果我們不在最後加了Response.Redirect方法,出錯後,用戶看到的就是那個很經典的黃顏色的報錯的頁面。我們也知道,那個經典的報錯頁面會暴露很多的信息,所以我們常常導航到我們自定義的錯誤頁面。
 
 
 


       二.頁面級的異常處理


       除了在Global.asax中編寫處理代碼,我們還可以在頁面的Page_Error中編寫代碼:

 public void Page_Error(object sender, EventArgs e)
 {
  
//Insert same code that is in the Application_Error event.
 }


 
       如果在該頁面中發生了錯誤,那麼頁面中的上面的那段代碼就會執行,我們可以把之前寫在Application_Error事件中的代碼全部copy到Page_Error處理方法中。但是,如果這樣,那麼我們的Application_Error中的代碼就不運行了,因爲異常已經在之前,也就是Page_Error中被處理了。
 
       三 方法級別的處理
       相信這點大家非常的熟悉了,就是常見的try..catch..finally語句塊的運用,這裏不贅述。
 
       四 web.config配置 

      我們處理異常一般在web.config文件中配置 <customErrors />節點:
            

 <customErrors mode="RemoteOnly" defaultRedirect="ErrorPage.aspx">
  
<error statusCode="403" redirect="NoAccess.htm" />
  
<error statusCode="404" redirect="FileNotFound.htm" />
 
</customErrors>

 

       節點中的一些屬性,大家也應該很熟悉,我不羅嗦了。

       五 健康監視(Health Monitoring)
 
       Health Monitoring是ASP.NET2.0以後版本添加的新的特性。它可以允許開發人員監視應用程序中發生的異常的事件。而且監視應用程序的啓動,關閉,驗證等都有相對應的事件來監視。而且我們還可以創建自定義的事件來監視應用程序中的特定的部分。我們也可以在Health Monitoring中配置把應用程序中的異常是記錄在系統的日誌中還是Sql Server中,或者是以Email形式發送出去。最重要的一點就是:只要通過配置,我們可以少寫,甚至不寫代碼就可以實現強大的異常處理策略(和類似Enterprise Application Blocks,我們後面會提到的)。
 

       同樣,我們還是在web.config中添加配置,在system.web節點中添加<healthMonitoring />節點:

       默認情況下是禁用的,我們啓用就應該如下:
 
 
   

<healthMonitoring enabled=”true>
  
<eventMappings></eventMappings>
  
<providers></providers>
  
<rules>..</rules>
  
<profiles>..</profiles>
  
<bufferModes>..</bufferModes>
 
</healthMonitoring>

 

       下面就看看該節點下的一些配置:
       eventMappings節點通過指定事件類型來註冊事件類。也就說,要註明我們在應用程序中要監聽哪些事件,如下配置:

 <eventMappings>
  
<clear />
  
<add name=”CustomException” type=”System.Web.Management.WebBaseErrorEvent” />
 
</eventMappings>


 
       前面的"name"屬性是我們自己爲後面的事件取的友好的名稱,從<eventMappings>的字面意思也可以知道:事件的映射。
       後面的"type"就是我們要在程序中監聽的事件。之前也說過,我們可以監聽很多的事件:系統的啓動,關閉,驗證失敗等。

       如上所見:"System.Web.Management.WebBaseErrorEvent" 是所有事件的基類。它的子類有很多:

       WebApplicationLifetimeEvent--在應用程序的運行過程觸發的事情,如,當應用程序開啓,關閉時
       WebAuthenticationFailureAuditEvent--當ASP.NET驗證失敗是觸發
       WebAuthenticationSuccessAuditEvent--驗證成功時觸發
       WebRequestErrorEvent--請求出錯時觸發
 
       除此之外,我們還可以自定義一些類,派生自基類。
 
 
       當我們確定了要監聽的事件之後,我們就要選擇事件的provider,也就說,事件觸發後,我們把事情的信息記錄到那裏。
       配置如下:
 

 <providers>
  
<clear />
  
<add name=”EventLogProvider” type=”System.Web.Management.EventLogWebEventProvider” />
 
</providers>


 
       這之前一樣:System.Web.Management.EventLogWebEventProvider是個基類,有很多的子類,這些子類可以使得我們把異常的記錄在如sql數據庫中,系統日誌中等:
       SqlWebEventProvider--把異常信息記錄到數據庫中的提供程序
       SimpleMailEventProvider--把異常信息通過Email發送的提供程序
 
       還有一些,大家參看MSDN。
 
       好了,到這裏,我們把要監聽的事件選擇好了,如要監聽WebApplicationLifetimeEvent,WebRequestErrorEvent;而且我們也準備把異常系統通過Email發送,我們選擇了SimpleMailEventProvider,通過也想把異常記錄到數據庫中,我們也選擇了SqlWebEventProvider。那麼我們的配置就如下:
       


<healthMonitoring enabled=”true>
  
<eventMappings>
   
<clear />
   
<add name=”CustomException” type=”System.Web.Management.WebApplicationLifetimeEvent” />
   
<add name=”AnotherException" type=”System.Web.Management.WebRequestErrorEvent” />
  
</eventMappings>

  
<providers>
   
<clear />
   
<add name=”EmailProvider” type=”System.Web.Management.SimpleMailEventProvider” />
   
<add name=”SqlProvider” type=”System.Web.Management.WebRequestErrorEvent” />
  
</providers>
  
 
</healthMonitoring>


         注意:providers節點中的"name"屬性也是我們自己取的友好的名稱。

       好了,該定義的定義好了,現在還是不能按照我們的要求工作,那是因爲我們還缺少一個"規則":
       如下:

 

 


<rules>
  
<clear />
  
<add name=”Unhandled Exceptions Rule”
   eventName
=”Unhandled Exceptions”
   provider
=”EventLogProvider”
   
profile=”Default”
   
minInstances=”1”
   
maxLimit=”Infinite”
   
minInterval=”00:00:00” />
 
</rules>

 實際上,rules就是把我們之前定義的要監聽的事件和相應的provider對象上來:
 
 
<rules>
  
<clear />
  
<add name=”MyRules1”
   
eventName=”CustomException”
   
provider=”EmailProvider”
   
profile=”Default”
   
minInstances=”1”
   
maxLimit=”Infinite”
   
minInterval=”00:00:00” />
 
</rules>


        注意上面的name屬性,其實和之前一樣,我們是給這個規則取個名字而已。eventName就是之前我們定義的事件名稱,如"CustomException",provider爲之前定義的“EmailProvider” ,本條規則就是說,讓EmailProvider來處理CustomException的異常信息。其他的同理。
 
       最後一點要注意的就是:如果我們決定發送Email,那麼我們還要配置節點:
 

<system.net>
  
<mailSettings>
   
<smtp deliveryMethod=”PickupDirectoryFromIis”>
    
<network defaultCredentials=”true” host=”127.0.0.1” />
   
</smtp>
  
</mailSettings>
 
</system.net>

 

       這樣就行了。
 


       六 Enterprise Application Blocks 

      關於Enterprise Application Blocks,相信大家都知道,在異常處理的時候我們一般用Exception Handling Application Block(後面簡稱 :異常處理的模塊),Logging Application Block。
       在決定用Enterprise Application Blocks的時候,我們必須首先下載安裝包. 
       得到了安裝包之後,我們就開始安裝,如果在安裝的過程中,全部採用默認的安裝設置,那麼我們就會有c:/EntLib4Src/Quick Starts文件夾。而且在ExceptionHandling/CS子文件夾下有ExceptionHandlingBasicQuickStart.sln 和ExceptionHanldingWithLoggingQuickStart.sln。打開ExceptionHandlingWithLoggingQuickStart解決方案,這個方案是個告訴我們如果使用異常處理模塊的Demo。


       而且這個Demo是WinForm的,因爲我們談的是在ASP.NET使用異常處理的模塊。所以我們談談在ASP.NET如何使用。
       在此之前,我們要熟悉一些配置節點,其實這些節點的結構和我們之前談的"健康監視"很相似:

 <exceptionTypes>
  
<add name=”Exception” type=”System.Exception, mscorlib, Version=2.0.0.0,
   
Culture=neutral, PublicKeyToken=b77a5c561934e089” postHandlingAction=”None”>

 
</exceptionTypes>


       上面節點表示要處理的異常,和之前的<eventMappings>相似。

 

 <exceptionHandlers>
  
<add name=”Application Message Handler” type=”ExceptionHandlingQuickStart.AppMessageExceptionHandler,
   
ExceptionHandlingWithLoggingQuickStart”/>
 
</exceptionHandlers>

 

       異常處理模塊,就是異常發生後,如何處理。和之前的providers節點類似。
 
       下面的節點,看起來很嚇人的,其實是聲明異常信息以什麼格式記錄:

 

<formatters>
  
<add name=”Default Formatter”
   type
=”Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter,
   
Microsoft.Practices.EnterpriseLibrary.Logging”
   template
=”Timestamp: {timestamp}
   Message: {message}
   Category: {category}
   Priority: {priority}
   EventId: {eventid}
   Severity: {severity}
   Title:{title}
   Machine: {machine}
   Application Domain: {appDomain}
   Process Id: {processId}
   Process Name: {processName}
   Win32 Thread Id: {win32ThreadId}
   Thread Name: {threadName}
   Extended Properties: {dictionary({key} - {value})}”
  
/>


       最後的節點如下,也不難理解,和之前說的rules節點類似:
             


<listeners>
  
<add name=”Event Log Destination”
   type
=”Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.Formatt        edEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging”
    listenerDataType
=”   Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData,
   Microsoft.Practices.EnterpriseLibrary.Logging”
   source 
=”Enterprise Library Logging”
   formatter
=”Default Formatter”
  
/> 
 
 
</listeners>

 

       其實Enterprise Application Blocks的功能不僅強大,而且還有最大的好處就是可以用GUI圖形化的形式來配置,不必項之前一樣要親自在配置文件中寫配置。而且在代碼調用方面也很簡單,幾句話就OK了。
 

       說完上面的之後,我們就用圖文結合的方式,展示如何使用異常處理模塊。      


       首先,我們把Program Files/Microsoft Enterprise Library 4.1 - October 2008/bin目錄下的幾個dll引入到我們的ASP.NET項目中:
       Microsoft.Practices.EnterpriseLibrary.Common
       Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
       Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging
       Microsoft.Practices.EnterpriseLibrary.Logging
       Microsoft.Practices.ObjectBuilder2

       下面開始配置:


       1.在我們的ASP.NET項目的web.config文件上點擊右鍵,就會彈出"Edit Enterprise Library Configuration"選項。點擊後就會看見如下界面:

 

 


       2.在彈出的界面中選中"web.config",點擊右鍵 "新建"-"Logging Application Block",這樣就把添加了日誌記錄的模塊的節點,如下:
       

 

 

       3.在默認情況下,在event log 的 trace listener節點有一個Trace Listeners,因爲我們要發送Email,所以要添加個e-mail trace listener。在Trace Listeners點擊右鍵,"新建"-"Email Trace Listener",之後就添加了"Email TraceListener"節點,然後選中"Email TraceListener",查看屬性,可以設置發送Email的設置。如圖:

 

 

 

 

             並且設置Formatter屬性並且選擇"Text Formatter",設置信息格式爲文本的形式。
 
       4.現在點擊"web.config"添加異常handler。"新建"-"Exception Handling Application Block",如下:
 


 
       然後在"Exception Handling Application Block"上右擊"新建"-"Exception Policy",然後我們可以重新命名爲"MyPolicy".然後在"MyPolicy"上右鍵,選中"New Exception Type",然後選擇我們要處理的異常,如圖:


 
       我們一般是選擇默認設置:處理所有異常。

 

       好了,現在我們把事件的處理程序也添加了,那麼下面就要加類似於"rules"的設置。
 
       5.在"Exception"節點上右擊"新建"-"Logging Handler",然後選擇"Logging Handler"節點,並且展開,選中"FormatterType",展開並且選"TextExceptionFormatter",最後確認就OK了。如下:
 
////

 

       6.然後在點擊"Logging Application Block/Special Source/All Events"的那個節點,右擊"新建"-"Trace Listener Reference"添加"Trace Listener Reference",並且設置"ReferencedTrace Listener"屬性爲"Email Trace Listener",最後保存就行了。

       7.我們在Global.asax文件下添加引用:
       

<%@ Import Namespace=”Microsoft.Practices.EnterpriseLibrary.ExceptionHandling” %>


       添加代碼:
 

void Application_Error(object sender, EventArgs e)
 {
  
// Code that runs when an unhandled error occurs
  ExceptionPolicy.HandleException(Server.GetLastError(), “Global Policy”);
 }


 
       就行了,強大異常處理就成功了。

 

       今天到這裏,謝謝

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章