前言:異常的處理在項(xiàng)目開發(fā)中是很有必要的,異常的處理不僅僅只是try..catch..finally就完事了的。異常處理絕對可以稱開發(fā)中的重要組成部分。必須正確的面對異常,由于即使是最能干的開發(fā)職員,也要面對這個題目 ....
我們不知道客戶是怎么樣使用我們開發(fā)的軟件的,所以我們必須處理這樣的情況:假如系統(tǒng)不按照我們的設(shè)計(jì)時所想的運(yùn)行,我們改怎么辦?
下面我們就來具體的介紹在ASP.NET項(xiàng)目開發(fā)中的異常的處理方式,希望看完后,大家可以回答上面的題目。
本篇的話題如下:
應(yīng)用程序級別異常處理的錯誤處理
頁面級別異常處理
方法級別異常處理
web.config文件異常處理配置
健康監(jiān)視(Health Monitoring)
Enterprise Application Blocks異常處理模塊
勇敢和必勝的信念常使戰(zhàn)斗得以勝利結(jié)束。 —— 恩格斯 一.在應(yīng)用程序級別的異常處理:
相信大家對Application對象不陌生,而且在項(xiàng)目中添加過Global.asax文件。確實(shí),ASP.NET在應(yīng)用程序級別處理異常的代碼都是放在Global.asax的Application_Error事件處理下的:
void Application_Error(object sender, EventArgs e)(// Code that runs when an unhandled error occurs}
我們可以在上面的事件處理的方法中捕捉所有的異常,而且還可以把異常記錄到日志文件,并且同時發(fā)送Email告訴開發(fā)職員出現(xiàn)了什么題目,
如下:
<Code>:
當(dāng)然,上面的代碼要正確的運(yùn)行,我們海必須在Global.asax中加入相應(yīng)的命名空間,而且在發(fā)送郵件的時候,上面的"127.0.0.1"要換為我們自己的郵件服務(wù)器的地址:
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.Net.Mail" %>
還有一點(diǎn)要留意的就是,ASP.NET運(yùn)行時是以ASPNET賬戶運(yùn)行的,這個賬戶的權(quán)限是有限的,假如我們想要使得上面的代碼可以運(yùn)行,那么就必須要給ASPNET賬戶訪問注冊表的權(quán)限。假如你不給權(quán)限,那么上面的代碼就報(bào)錯。
我們賦予ASPNET賬戶訪問在"HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventlog"節(jié)點(diǎn)以及字節(jié)點(diǎn)的權(quán)限。
下面就講講如何配置權(quán)限:
1.打開"運(yùn)行"菜單
2.輸入"regedit",然后確定
3.導(dǎo)航到"HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventlog"節(jié)點(diǎn)。
4.右擊這個節(jié)點(diǎn),并且選擇"權(quán)限",此時就會彈出權(quán)限配置的窗口。
5.點(diǎn)擊"添加",在彈出的窗口中點(diǎn)擊"高級",之后再點(diǎn)擊"查找",最后在下面的窗口找到"ASPNET"賬戶,確定。
6.最后給予ASPNET賬戶讀的權(quán)限就OK了。
上面的代碼,假如我們不在最后加了Response.Redirect方法,出錯后,用戶看到的就是那個很經(jīng)典的黃顏色的報(bào)錯的頁面。我們也知道,那個經(jīng)典的報(bào)錯頁面會暴露很多的信息,所以我們經(jīng)常導(dǎo)航到我們自定義的錯誤頁面。
二.頁面級的異常處理
除了在Global.asax中編寫處理代碼,我們還可以在頁面的Page_Error中編寫代碼:
public void Page_Error(object sender, EventArgs e)
{//Insert same code that is in the Application_Error event. }
假如在該頁面中發(fā)生了錯誤,那么頁面中的上面的那段代碼就會執(zhí)行,我們可以把之前寫在Application_Error事件中的代碼全部copy到 Page_Error處理方法中。但是,假如這樣,那么我們的Application_Error中的代碼就不運(yùn)行了,由于異常已經(jīng)在之前,也就是 Page_Error中被處理了。
三 方法級別的處理
相信這點(diǎn)大家非常的熟悉了,就是常見的try..catch..finally語句塊的運(yùn)用,這里不贅述。
四 web.config配置
我們處理異常一般在web.config文件中配置 <customErrors />節(jié)點(diǎn):
<customErrors mode="RemoteOnly" defaultRedirect="ErrorPage.aspx">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
節(jié)點(diǎn)中的一些屬性,大家也應(yīng)該很熟悉,我不羅嗦了。
五 健康監(jiān)視(Health Monitoring)
Health Monitoring是ASP.NET2.0以后版本添加的新的特性。它可以答應(yīng)開發(fā)職員監(jiān)視應(yīng)用程序中發(fā)生的異常的事件。而且監(jiān)視應(yīng)用程序的啟動,封閉,驗(yàn)證等都有相對應(yīng)的事件來監(jiān)視。而且我們還可以創(chuàng)建自定義的事件來監(jiān)視應(yīng)用程序中的特定的部分。我們也可以在Health Monitoring中配置把應(yīng)用程序中的異常是記錄在系統(tǒng)的日志中還是Sql Server中,或者是以Email形式發(fā)送出去。最重要的一點(diǎn)就是:只要通過配置,我們可以少寫,甚至不寫代碼就可以實(shí)現(xiàn)強(qiáng)大的異常處理策略(和類似 Enterprise Application Blocks,我們后面會提到的)。
同樣,我們還是在web.config中添加配置,在system.web節(jié)點(diǎn)中添加<healthMonitoring />節(jié)點(diǎn):
默認(rèn)情況下是禁用的,我們啟用就應(yīng)該如下:
+Code
下面就看看該節(jié)點(diǎn)下的一些配置:
eventMappings節(jié)點(diǎn)通過指定事件類型來注冊事件類。也就說,要注明我們在應(yīng)用程序中要監(jiān)聽哪些事件,如下配置:
<eventMappings>
<clear />
<add name=”CustomException” type=”System.Web.Management.WebBaseErrorEvent” />
</eventMappings>
前面的"name"屬性是我們自己為后面的事件取的友好的名稱,從<eventMappings>的字面意思也可以知道:事件的映射。
后面的"type"就是我們要在程序中監(jiān)聽的事件。之前也說過,我們可以監(jiān)聽很多的事件:系統(tǒng)的啟動,封閉,驗(yàn)證失敗等。
如上所見:"System.Web.Management.WebBaseErrorEvent" 是所有事件的基類。它的子類有很多:
WebApplicationLifetimeEvent--在應(yīng)用程序的運(yùn)行過程觸發(fā)的事情,如,當(dāng)應(yīng)用程序開啟,封閉時
WebAuthenticationFailureAuditEvent--當(dāng)ASP.NET驗(yàn)證失敗是觸發(fā)
WebAuthenticationSuccessAuditEvent--驗(yàn)證成功時觸發(fā)
WebRequestErrorEvent--請求出錯時觸發(fā)
除此之外,我們還可以自定義一些類,派生自基類。
當(dāng)我們確定了要監(jiān)聽的事件之后,我們就要選擇事件的provider,也就說,事件觸發(fā)后,我們把事情的信息記錄到那里。
配置如下:
<providers>
<clear />
<add name=”EventLogProvider” type=”System.Web.Management.EventLogWebEventProvider” />
</providers>
這之前一樣:System.Web.Management.EventLogWebEventProvider是個基類,有很多的子類,這些子類可以使得我們把異常的記錄在如sql數(shù)據(jù)庫中,系統(tǒng)日志中等:
SqlWebEventProvider--把異常信息記錄到數(shù)據(jù)庫中的提供程序
SimpleMailEventProvider--把異常信息通過Email發(fā)送的提供程序
還有一些,大家參看MSDN。
好了,到這里,我們把要監(jiān)聽的事件選擇好了,如要監(jiān)聽 WebApplicationLifetimeEvent,WebRequestErrorEvent;而且我們也預(yù)備把異常系統(tǒng)通過Email發(fā)送,我們選擇了SimpleMailEventProvider,通過也想把異常記錄到數(shù)據(jù)庫中,我們也選擇了SqlWebEventProvider。那么我們的配置就如下:
+Code:
<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節(jié)點(diǎn)中的"name"屬性也是我們自己取的友好的名稱。
好了,該定義的定義好了,現(xiàn)在還是不能按照我們的要求工作,那是由于我們還缺少一個"規(guī)則":
如下:
+Code:
留意上面的name屬性,實(shí)在和之前一樣,我們是給這個規(guī)則取個名字而已。eventName就是之前我們定義的事件名稱,如"CustomException",provider為之前定義的“EmailProvider” ,本條規(guī)則就是說,讓EmailProvider來處理CustomException的異常信息。其他的同理。
最后一點(diǎn)要留意的就是:假如我們決定發(fā)送Email,那么我們還要配置節(jié)點(diǎn):
<system.net>
<mailSettings>
<smtp deliveryMethod=”PickupDirectoryFromIis”>
<network defaultCredentials=”true” host=”127.0.0.1” />
</smtp>
</mailSettings>
</system.net>
這樣就行了。
六 Enterprise Application Blocks
關(guān)于Enterprise Application Blocks,相信大家都知道,在異常處理的時候我們一般用Exception Handling Application Block(后面簡稱 :異常處理的模塊),Logging Application Block。
在決定用Enterprise Application Blocks的時候,我們必須首先下載安裝包.
得到了安裝包之后,我們就開始安裝,假如在安裝的過程中,全部采用默認(rèn)的安裝設(shè)置,那么我們就會有c:EntLib4SrcQuick Starts文件夾。而且在ExceptionHandlingCS子文件夾下有 ExceptionHandlingBasicQuickStart.sln 和ExceptionHanldingWithLoggingQuickStart.sln。打開 ExceptionHandlingWithLoggingQuickStart解決方案,這個方案是個告訴我們假如使用異常處理模塊的Demo。
而且這個Demo是WinForm的,由于我們談的是在ASP.NET使用異常處理的模塊。所以我們談?wù)勗贏SP.NET如何使用。
在此之前,我們要熟悉一些配置節(jié)點(diǎn),實(shí)在這些節(jié)點(diǎn)的結(jié)構(gòu)和我們之前談的"健康監(jiān)視"很相似:
<exceptionTypes>
<add name=”Exception” type=”System.Exception, mscorlib, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089” postHandlingAction=”None”>
</exceptionTypes>
上面節(jié)點(diǎn)表示要處理的異常,和之前的<eventMappings>相似。
<exceptionHandlers>
<add name=”Application Message Handler” type=”ExceptionHandlingQuickStart.AppMessageExceptionHandler,
ExceptionHandlingWithLoggingQuickStart”/>
</exceptionHandlers>
異常處理模塊,就是異常發(fā)生后,如何處理。和之前的providers節(jié)點(diǎn)類似。
下面的節(jié)點(diǎn),看起來很嚇人的,實(shí)在是聲明異常信息以什么格式記錄:
+Code
最后的節(jié)點(diǎn)如下,也不難理解,和之前說的rules節(jié)點(diǎn)類似:
+Code
實(shí)在Enterprise Application Blocks的功能不僅強(qiáng)大,而且還有最大的好處就是可以用GUI圖形化的形式來配置,不必項(xiàng)之前一樣要親安閑配置文件中寫配置。而且在代碼調(diào)用方面也很簡單,幾句話就OK了。
說完上面的之后,我們就用圖文結(jié)合的方式,展示如何使用異常處理模塊。
首先,我們把Program FilesMicrosoft Enterprise Library 4.1 - October 2008in目錄下的幾個dll引入到我們的ASP.NET項(xiàng)目中:
Microsoft.Practices.EnterpriseLibrary.Common
Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging
Microsoft.Practices.EnterpriseLibrary.Logging
Microsoft.Practices.ObjectBuilder2
下面開始配置:
1.在我們的ASP.NET項(xiàng)目的web.config文件上點(diǎn)擊右鍵,就會彈出"Edit Enterprise Library Configuration"選項(xiàng)。點(diǎn)擊后就會看見如下界面:
2.在彈出的界面中選中"web.config",點(diǎn)擊右鍵 "新建"-"Logging Application Block",這樣就把添加了日志記錄的模塊的節(jié)點(diǎn),如下:
3.在默認(rèn)情況下,在event log 的 trace listener節(jié)點(diǎn)有一個Trace Listeners,由于我們要發(fā)送Email,所以要添加個e-mail trace listener。在Trace Listeners點(diǎn)擊右鍵,"新建"-"Email Trace Listener",之后就添加了"Email TraceListener"節(jié)點(diǎn),然后選中"Email TraceListener",查看屬性,可以設(shè)置發(fā)送Email的設(shè)置。如圖:
并且設(shè)置Formatter屬性并且選擇"Text Formatter",設(shè)置信息格式為文本的形式。
4.現(xiàn)在點(diǎn)擊"web.config"添加異常handler。"新建"-"Exception Handling Application Block",如下:
然后在"Exception Handling Application Block"上右擊"新建"-"Exception Policy",然后我們可以重新命名為"MyPolicy".然后在"MyPolicy"上右鍵,選中"New Exception Type",然后選擇我們要處理的異常,如圖:
我們一般是選擇默認(rèn)設(shè)置:處理所有異常。
好了,現(xiàn)在我們把事件的處理程序也添加了,那么下面就要加類似于"rules"的設(shè)置。
5.在"Exception"節(jié)點(diǎn)上右擊"新建"-"Logging Handler",然后選擇"Logging Handler"節(jié)點(diǎn),并且展開,選中"FormatterType",展開并且選"TextExceptionFormatter",最后確認(rèn)就OK了。如下:
6.然后在點(diǎn)擊"Logging Application BlockSpecial SourceAll Events"的那個節(jié)點(diǎn),右擊"新建"-"Trace Listener Reference"添加"Trace Listener Reference",并且設(shè)置"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”);
}