在Model綁定過程中會通過激活的Controller類型創建用於描述它的 ControllerDescriptor對象。Controller是一組Action方法的集合,而每一個 Action通過ActionDescriptor對象來表示,在這篇文章中我們就來著重談談不同 類型的ActionDescriptor。[本文已經同步到《How ASP.NET MVC Works?》中]
一、ActionDescriptor
用於描述定義在Controller類中的Action方法的ActionDescriptor定義如下。 屬性ActionName和ControllerDescriptor表示Action的名稱和描述所在 Controller的ControllerDescriptor對象。表示唯一標識的UniqueId屬性由自身 類型、Controller的類型與Action名稱三者派生。
1: public abstract class ActionDescriptor : ICustomAttributeProvider
2: {
3: public virtual object[] GetCustomAttributes(bool inherit);
4: public virtual object[] GetCustomAttributes(Type attributeType, bool inherit);
5: public virtual bool IsDefined(Type attributeType, bool inherit);
6: public virtual IEnumerable<FilterAttribute> GetFilterAttributes( bool useCache);
7:
8: public abstract ParameterDescriptor[] GetParameters();
9: public abstract object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters);
10: public virtual ICollection<ActionSelector> GetSelectors();
11: public virtual FilterInfo GetFilters();
12:
13: public abstract string ActionName { get; }
14: public abstract ControllerDescriptor ControllerDescriptor { get; }
15: public virtual string UniqueId { get; }
16: }
與ControllerDescriptor一樣,ActionDescriptor同樣實現了定義在 ICustomAttributeProvider接口中的方法,我們可以通過相應的方法得到應用在 Action方法上的相關特性,或者判斷某個指定的特性是否應用在對應的Action方 法上。GetFilterAttributes方法用於返回應用在Action方法上的所有篩選器特性 。用於描述Action方法中所有參數的ParameterDescriptor數組通過方法 GetParameters返回。Action方法的執行可以直接通過調用方法Execute來完成, 該方法的兩個參數controllerContext和parameters分別代表Action方法執行所在 的Controller上下文和傳入的參數。
GetSelectors方法用於返回一組表示Action選擇器的類型為ActionSelector的 對象,而ActionSelector是一個委托類型。如下面的代碼片斷所示, ActionSelector委托具有唯一的類型為ControllerContext的參數,布爾類型的返 回值表示目標Action方法是否與指定的Controller上下文相匹配。該方法默認返 回的是一個空的ActionSelector集合。
1: public delegate bool ActionSelector(ControllerContext controllerContext);
ActionDescriptor的GetFilters方法返回的是一個FilterInfo類型的對象,我 們通過這個對象可以得到應用在該Action方法上所有的篩選器。如下面的代碼所 示,FilterInfo具有四個只讀的集合屬性,分別代碼應用在該Action方法上的四 種類型的篩選器(ActionFilter、AuthorizationFilter、ExceptionFilter和 ResultFilter)。
1: public class FilterInfo
2: {
3: public IList<IActionFilter> ActionFilters { get; }
4: public IList<IAuthorizationFilter> AuthorizationFilters { get; }
5: public IList<IExceptionFilter> ExceptionFilters { get; }
6: public IList<IResultFilter> ResultFilters { get; }
7: }
二、AsyncActionDescriptor
異步版本的ActionDescriptor通過AsyncActionDescriptor類型表示,它用於 描述定義在AsyncController中的異步方法。如下面的代碼片斷所示, AsyncActionDescriptor是一個繼承自ActionDescriptor的抽象類,它重寫了 Execute方法,並且定義了兩個用於異步執行Action方法的抽象方法 BeginExecute/EndExecute。
1: public abstract class AsyncActionDescriptor : ActionDescriptor
2: {
3: public abstract IAsyncResult BeginExecute( ControllerContext controllerContext, IDictionary<string, object> parameters, AsyncCallback callback, object state);
4: public abstract object EndExecute(IAsyncResult asyncResult);
5: public override object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters);
6: }
實際上AsyncActionDescriptor重寫的Execute方法並沒有實現任何Action方法 執行的邏輯,而是直接拋出一個InvalidOperationException異常,意味用於同步 執行Action操作的Execute方法在這裡無效。