本文實例講述了C#自定義HttpFilter模塊完善的方法,分享給大家供大家參考。具體實現方法如下:
一、背景
近期由于要針對項目做用戶操作日志,但不想在每個方法里去增加代碼,寫入用戶日志。因為這樣具體的方法違背職責單一的原則,若后期日志內容格式發生變更,或其他什么需求,該方法代碼主要一變在變,故使用HttpModule模塊來完成此功能,感興趣的朋友可以參考:關于HttpHandler與HttpModule的理解和應用方法
經過實際運用與完善,現在可以再次總結下。
二、攔截時機
現在的版本中,攔截的依據是,在每次請求發生的過程中,攔截控制器類請求,重定向http輸出流,并分析出Controller與Action,接下來查找是否有方法監控了此控制器,若有,則分析出請求輸入參數,與此次請求輸出內容,存儲在FilterContext中,交給該方法,完成相應邏輯。
由于在最初的寫法中,是針對所有的請求進行流的重定向,在asmx下,會遇到問題,只要重定向了,調用服務的客戶端會提示400 Http Bad Request 。這個具體的錯誤原因,還不清楚,但正是由于該錯誤,讓我發現,我之前攔截的時機是錯誤的,理應放在請求之前,判斷是否滿足攔截的規則,若滿足,則重定向輸出流。
三、讀取用戶名
在Module模塊中總會出點問題,最后使用了Cookie記住用戶名,并直接定義為FilterContext一個屬性。解釋下這樣做的原因:由于記住用戶名的方式有很多,如Session、Cookie,即讀取用戶名的方式是可變的,所以盡可能將變化的內容在前面解決,這樣監聽控制器的方法,直接根據該屬性獲取用戶名,否則用戶名的讀取時機,放在每個監聽控制器模塊之后,讀取方式一旦發生變更,所有的模塊都要改變,當然也可以通過繼承一個base類來避免這么大的改變。
在這里我想表達的意思是:我們做類似底層庫的東西,盡可能穩定,將變化點集中在庫本身,這樣依賴該庫的應用才能穩定。若.net版本更新過程中,API都不穩定,想必我們也不會在去使用它。
四、應用之寫入日志
典型例子如下:
該方法表達的意思是,監控LoginController的Login方法。由于我們需要分析請求輸出結果,所以分析的規則,與控制器是強依賴的,控制器的方法是怎么返回數據的,我們此處就要根據規則解析。我在項目中使用的是Json,所以監控的地方都需要Json的反序列化,這里僅僅是一個Demo。
另外一個方法可以監聽一個控制器下的多個方法,或者多個控制器。這樣是旨在解決有很多Action,輸入參數和輸出參數都是相同的,可能由于業務不同,僅僅在方法名和內部實現中有不同。
五、應用之更新緩存
首先關于Cache的應用,可以讀下此文章,Asp.Net Cache高級用法。
由于此處我沒有寫例子,先描述我在項目中運用的情況。系統有很多數據字典,在請求該數據字典時,程序首先從數據庫加載字典數據,并放入緩存,此時放入緩存有個技巧,設置過期時間,并設置移除緩存前的回調,我們來看看具體的方法定義:
仔細看看onUpdateCallback參數的描述:從緩存中移除對象之前將調用的委托??梢允褂盟鼇砀戮彺骓棽⒋_保緩存項不會從緩存中移除。
我在把數據字典放入緩存的同時傳遞讀取緩存的委托,這樣在主動移除緩存或者緩存過期時都將再次調用此委托,將數據字典再次放入緩存。所以一旦數據字典發生了變更,如增刪改,那么就主動將字典緩存移除,它就可以自動更新過來,是不是很方便呢。
區別于寫操作日志,不過是處理邏輯發生了變化,他們都需要請求的輸入和輸出。
六、其他
1.由于使用HttpModule來完成此功能,如需正常運行,需要在WebConfig中注冊該模塊。詳見Demo。
2.項目中使用了Log4Net記錄文本日志,并可以根據功能分類。詳見:Log4Net日志分類維護。
完整實例代碼點擊此處本站下載。
希望本文所述對大家的C#程序設計有所幫助。
新聞熱點
疑難解答