深入理解ASP.NET MVC(7)

來源:互聯網
上載者:User

系列目錄

Action的定位

再次回到Controller的ExecuteCore方法,回到action調用的入口:

if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) 

這裡的ActionInvoker是個IActionInvoke,它無疑是負責了所有action的調用邏輯,MVC中預設實現這個介面的是ControllerActionInvoke。可以想象ControllerActionInvoke面臨的第一個問題是如何找到與actionName對應的action。

首先,並不是所有的action都合法,需要符合下麵條件:

1、Public,非static

2、非Controller或其基類定義的方法,比如ToString(),GetHashcode()

3、不能是特殊名字System.Reflection.MethodBase的IsSpecialName標誌,例如建構函式,屬性包裝器,事件封裝器

4、具有泛型參數的方法儘管會被認為是action,但架構試圖執行這樣的action時會只是拋出異常。

其次,MVC為action的尋找過程設計了兩種“選取器”

  • ActionNameSelectorAttribute
  • ActionMethodSelectorAttribute

如果對此比較迷茫的話,看了他們的派生特性,你也許就明白了:

 

 

我們常用ActionNameAttribute來“偽裝”;用HttpPostAttributeHttpGetAttribute來說明某個action符合的特定的http行為;用NoAction隱藏我們不想“暴露給url”的方法…其實這些行為的原理便是利用MVC為我們提供的action選擇的機制。下面這張圖說明了這個過程的完成邏輯:

ContollerActionInvoker.InvokeAction在內部建立一個ReflectedControllerDescriptor,並調用其FindAction方法,這個對象的FindAction負責調用一個ActionMethodSelector對象實現上述邏輯,並在最後返回一個ReflectedActionDescriptor。ActionMethodSelector對象故名思意,原理上用反射執行上述過程,執行的結果要麼返回一個MethodInfo,要麼返回null,要麼拋出異常。ReflectedControllerDescriptor對傳回值判斷,如果是null,則也返回null;如果是MethodInfo,則將其封裝成ReflectedActionDescriptor返回。對於外面的InvokeAction方法來說只要ReflectedControllerDescriptor返回的ReflectedActionDescriptor為空白就返回false,否則繼續。Controller負責對返回false的情況調用HandleUnknownAction,該方法預設產生404錯誤,我們可以重寫它。

在回過頭來看看的邏輯,不難得到這樣一個事實:ActionNameSelectorAttribute優先於ActionMethodSelectorAttribute,ActionMethodSelectorAttribute優先於沒有ActionMethodSelectorAttribute特性的方法

更多關於這部分源碼的細節,可以參考:通過原始碼研究ASP.NET MVC中的Controller和View(六)

 

MVC的內建過濾器

ActionDescriptor(ReflectedActionDescriptor)返回後,ContollerActionInvoker開始執行action,但是在執行action前還有一些額外的步驟,那就是過濾。以下四個是MVC內建的過濾介面:

  • IActionFilter
  • IAuthorizationFilter
  • IExceptionFilter
  • IResultFilter

這四個Filter會被ControllerActionInvoker架構綜合考量,下面的虛擬碼說明了ControllerActionInvoker處理他們的邏輯順序:

try{//依次執行IAuthorizationFilterRun each IAuthorizationFilter's OnAuthorization() method//所有的IAuthorizationFilter都返回null而不是ActionResultif(none of the IAuthorizationFilters cancelled execution){Run each IActionFilter's OnActionExecuting() methodRun the action method//注意到這裡按照反轉順序進行Run each IActionFilter's OnActionExecuted() method (in reverse order)Run each IResultFilter's OnResultExecuting() methodRun the action result//注意到這裡按照反轉順序進行Run each IResultFilter's OnResultExecuted() method (in reverse order)}//有IAuthorizationFilter返回ActionResultelse{Run any action result set by the authorization filters}}catch(exception not handled by any action or result filter){//注意到IExceptionFilter處理的異常只在這個try catch塊中Run each IExceptionFilter's OnException() methodRun any action result set by the exception filters}

需要注意的事項,在代碼中都已經給出注釋,在後面一節中,將討論其中的某些細節。

MVC中與這四個介面相關的特性如下:

我們熟悉的有AuthorizeOutputCacheChildAction等。曾經,對於這些形形色色的Attribute,我都不能很好的理解和歸類,現在總算是找它們各自的歸宿了。

下一節,將針對這四個過濾器介面深入討論一些細節問題。

 

勞動果實,轉載請註明出處:http://www.cnblogs.com/P_Chou/archive/2010/12/01/details-asp-net-mvc-07.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.