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