ASP.NET MVC框架內(nèi)置了攔截Action的機(jī)制。確切的分為:Action攔截器、Result攔截器和Exception攔截器三種。所謂 ASP.NET MVC攔截器,就是一個普通的類,該類需要繼承FilterAttribute基類,Action攔截器還要實(shí)現(xiàn)IActionFilter接口,而Exception攔截器需要實(shí)現(xiàn)IExceptionFilter接口。 Action執(zhí)行過濾的接口為:IActionFilter,它有兩個方法,OnActionExecuted:作用是Action執(zhí)行后過濾;OnActionExecuting:Action執(zhí)行前過濾。而FilterAttribute則表示用在屬性上的成員篩選器。 一、日志攔截器 這個類繼承了FilterAttribute并實(shí)現(xiàn)了接口的IActionFilter的兩個方法:OnActionExecuting在被攔截Action前執(zhí)行了準(zhǔn)備寫入日志操作,OnActionExecuted在被攔截Action后執(zhí)行操作完成日志。兩個方法都有一個參數(shù),雖然類型不同,但其實(shí)都是一個作用:被攔截Action的上下文。 二、異常攔截器 異常攔截器一樣需要繼承FilterAttribute,但是不要實(shí)現(xiàn)IActionFilter,而是要實(shí)現(xiàn)IExceptionFilter接口,這個接口只有一個方法:OnException,顧名思義,當(dāng)然是發(fā)生異常時被調(diào)用了。我們看看我讓它做了什么:首先將異常信息(ExceptionContext一樣也是上下文,而其成員的Exception就是一個Exception類型的實(shí)例,就是被拋出的異常)記錄到ViewData相應(yīng)的鍵值里,然后我們要呈現(xiàn)Error這個視圖。注意!這里已經(jīng)不是Controller里了,而是另一個類,所以當(dāng)然不能調(diào)用View方法返回ViewResult實(shí)例了。我們只好新建一個ViewResult實(shí)例,并將其視圖名設(shè)為Error,將上下文中的DataView傳過去。最后那行filterContext.ExcepitonHandled = true;很重要,這行的意思是告訴系統(tǒng),異常已經(jīng)處理,不要再次處理了。使用攔截器固然很爽,但是要注意兩個地方:1.Action攔截器的作用范圍除了用Action攔截器標(biāo)記一個Action方法外,你也可以用來標(biāo)記一個完成的控制器類。如果這樣的話,這個Action攔截器將會應(yīng)用到該控制器的所有Action方法上。另外,如果你的控制器類繼承自別的控制器類,而基控制器類可能有它自己的Action攔截器Attributes。如果你在子類中重寫了基控制器類的Action方法,則子類的該Action方法也會有它自己的從基類繼承而來的Action攔截器Attributes。2.Action攔截器的執(zhí)行順序每一個Action攔截器都有一個 Order 屬性,用來決定Action攔截器在該范圍內(nèi)的執(zhí)行順序。Order屬性必需是0(默認(rèn)值)或者更大的整數(shù)值。省略O(shè)rder屬性則會給該攔截器的Order值為 -1, 表明為指明順序。任何一個在同一范圍的Action攔截器Order設(shè)為 -1 的都將按不確定的順序執(zhí)行,單在此之前攔截器有一個特定的順序(注:下面會說到).當(dāng)設(shè)置Order屬性的值的時候,必需指定一個唯一的值。如果兩個或者更多的Action攔截器具有相同的Order屬性值,將會拋出一個異常。來看一個示例:[Filter1(Order = 2)] [Filter2(Order = 3)] [Filter3(Order = 1)] public void Index() { RenderView("Index"); }Filter的執(zhí)行順序?yàn)椋篎ilter3 => Filter1 => Filter2. 綜上所述,使用攔截器顯而易見的優(yōu)點(diǎn): 1. 解決了部分代碼重復(fù)的問題。很多日志處理代碼和異常處理代碼是很相似的,這樣就導(dǎo)致了各個Action中存在大量重復(fù)代碼。 2. 職責(zé)的明確化。 Controller僅僅是控制器,只負(fù)責(zé)表示邏輯,而不應(yīng)該被一大堆日志處理代碼和try...catch塊包圍。我們要的Action,應(yīng)該是干凈的、工整的、僅包含表示邏輯的Action。 3. 代碼更加優(yōu)雅。 當(dāng)然了,也有他的缺點(diǎn),在 ASP.NET MVCController中一個Action最好不要超過2,3個帽子(攔截器或過濾器),否則性能會受到影響。 |
|