最近有點事,把這個系列給落下了,給你們道個歉,這裏還要感謝個人老婆,謝謝她一直對個人支持:)html
系列回顧:web
1.異常處理--Exception(一)數據庫
上一篇中主要介紹了Log的幾種方式,接下來講說通知的方式:服務器
通知方式架構 |
說明app |
Emailpost |
這是最多見也是最方便的一種通知方式。網站 優勢:使用簡單url 缺點:須要依賴於SMTP服務器等 |
SMS |
這也是目前比較流行的通知方式,不過通常不會把全部信息都經過短信進行發送,能夠選幾個比較關鍵的Exception進行SMS通知。 缺點:字數、網關、接口等限制。 優勢:及時性 |
Post |
經過某種服務,對客戶端進行Post Exception。 優勢:及時性(不過依賴於客戶端) 缺點:須要編寫安全的客戶端程序。 |
Get |
跟Post優勢相似,但須要把Exception先存到某個地方,而後Get的時候獲取。 |
Other |
還有不少通知的方式,這個取決於你們的需求了。 |
通常咱們經常使用的是前2種方式,由於編寫還算簡單,SMS的接口如今也有不少了。
注:若是在你的程序種有Email發送程序的話,我建議您仍是不要使用相同的配置進行發送,建議從新創建一個新的配置,包括髮送方式都使用一個新的方法。
這裏值得注意的是,當你的Email通知方式拋出異常時,請必定要使用另一種方式進行通知,由於此時可能你的網站已經發生了不可忽視的異常了。
通知的信息內容比較簡單,若是是Email發送方式,就可使用Log的Log信息進行發送,若是SMS的話,你可使用模板,或者固定格式進行發送。
通知的內容不是不少,下面來討論一下 Try / Catch
這個問題原本先前就想說的,前幾天也看到楊兄弟的「請討論try...catch..寫在不一樣地方,有何利害? 」其中討論的很是激勵,不少人說的都比較正確,使我以爲或許個人方案不是最好的,但我決定仍是把個人見解寫出來,這樣才能你們一塊兒來進行討論。老趙說在內部類的時候最好也能把異常捕捉後,進行封裝而後再拋出,不過我我的以爲,若是是類庫的話,仍是不要去Catch,這是爲何呢?
我認爲,類庫中的方法是咱們程序的最小單元,它的存在是爲了咱們高層的調用,它的存在必有它的意義,就算它內部調用其餘類庫的方法(大多會調用FCL),咱們最好不要去Catch掉,不過某些時候你可能要違反這個規則,但請記住,封裝好你的異常,而後Throw到高層,那樣才能不遺漏你的程序發生的Exception。類庫中的方法,若是會調用不少其餘類庫的方法時,你應該考慮你的這個類庫或許已經存在了幾種可能性改變你的結果了,你該好好的從新設計你的方法。
如今說說個人觀點,通常咱們的網站會使用三層架構,不過爲了解除業務邏輯與頁面層的耦合,咱們會藉助某些模式,以下降它的耦合度。(本身的想法,或許某些概念會錯誤)
咱們的網站大可能是對數據庫的I、U、D、S的操做,因此數據層基本已經屬於了底層類庫,業務層進行調用,UI層進行顯示信息。(那咱們是否是對數據層的異常不進行處理呢?也不必定,若是按照我先前說的,最好是不要在底層進行處理,沒有錯,但咱們不能太絕對,仍是根據你的項目來分析後進行安排吧。)
有人會說在數據層,咱們會使用ADO等方法,會與數據庫進行必定的聯繫,其中就會拋出各類異常,難道咱們不要去處理嗎?是的,若是可能,請不要在這裏進行處理,個人方案是,去業務層進行捕捉和處理。
業務層咱們是否是去把全部異常都處理了呢?請不要這樣設想,由於有些異常不是你能所有處理的,咱們應該把咱們能預知的,咱們須要的異常進行處理(姑且把咱們的處理程序定義爲ExceptionManager)丟到ExceptionManager中進行處理。但咱們有時須要拋出一些Exception Message給用戶,因此這些異常,請封裝好,繼續往高層Throw,這時,請不要把異常丟到ExceptionManager中,由於後面咱們會有其餘地方進行處理的。
到此,輪到咱們的UI層了,UI層直接面對的是用戶,在咱們先前說的,咱們必須記錄下咱們的異常,讓後給用戶呈現一個友好的用戶界面,那樣纔是作網站的王道。在web.config中,能夠設置發生錯誤時所呈現的一個頁面Url,雖然這麼作能夠給用戶一個好的友好界面,但有時,咱們須要給用戶提供更多的信息,好比請輸入用戶名等,這時候config配置的頁面就沒法達到咱們的要求了,那咱們該如何來作呢?
其實很簡單,使用一個HttpModule就能夠了,在這個Module中不要牽涉到其餘任何東西,由於在Asp.Net中,一個請求的順序會把你全部的Module都會執行一次,因此沒必要擔憂.Net會遺漏,咱們只須要配置好就能夠了。那咱們這個Module只要作哪些工做呢?只須要處理未處理的異常,首先看一段代碼:
ExceptionHandlingModule 1public class ExceptionHandlingModule : IHttpModule { IHttpModule 成員#region IHttpModule 成員 public void Dispose() { } public void Init(HttpApplication context) { context.Error += new EventHandler(context_Error); } void context_Error(object sender, EventArgs e) { var application = (HttpApplication)sender; //獲取當前請求的前一個錯誤 //這裏的GetLastError 實際上是一個封裝好的Exception //咱們若是想要知道真正的Exception的話,須要用InnerException屬性獲取。 var unHandlingException = application.Context.Server.GetLastError(); if (unHandlingException != null) { unHandlingException = unHandlingException.InnerException; if (unHandlingException != null) { ExceptionManager.HandlingException(unHandlingException); //好了,咱們已經把unHandlingException處理了,後面就清除吧 application.Context.ClearError(); //固然,若是你想要用戶看到錯誤提示信息的話,記得把Message保留下來 } } } #endregion }
第三篇就說到這裏吧,接下來後面將會把自定義異常、處理的代碼給你們說明一下。
其實不少內容都是通過修改了,原先的想法在我寫博客的時候,感受愈來愈不對勁,看來我還得加把勁,有些地方或許說的不是很合理,也但願你們能給我提出建議,以避免誤導其餘讀者:)