ASP.NET MVC應用的請求都是針對某個Controller的某個Action方法,所以對 請求的處理最終體現在對目標Action方法的執行。而Action方法具有相應的參數 ,所以在方法執行之前必須根據相應的規則從請求中提取相應的數據並將其轉換 為Action方法參數列表,我們將這個過程稱為Model綁定。在ASP.NET MVC應用編 程接口中,Action方法某個參數的元數據通過ParameterDescriptor表示,而兩個 相關的類型ControllerDescriptor和ActionDescriptor則用於描述Controller和 Action方法。[本文已經同步到《How ASP.NET MVC Works?》中]
一、ControllerDescriptor
ControllerDescriptor包含了用於描述某個Controller的元數據信息。如下面 的代碼片斷所示,ControllerDescriptor具有三個屬性,其中ControllerName和 ControllerType分別表示Controller的名稱和類型,前者來源於路由信息;字符 串類型的UniqueId表示ControllerDescriptor的唯一標識,該標識由自身的類型 、Controller的類型以及Controller的名稱三者派生。
1: public abstract class ControllerDescriptor : 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 ActionDescriptor FindAction(ControllerContext controllerContext, string actionName);
9: public abstract ActionDescriptor[] GetCanonicalActions();
10:
11: public virtual string ControllerName { get; }
12: public abstract Type ControllerType { get; }
13: public virtual string UniqueId { get; }
14: }
15:
16: public interface ICustomAttributeProvider
17: {
18: object[] GetCustomAttributes(bool inherit);
19: object[] GetCustomAttributes(Type attributeType, bool inherit);
20: bool IsDefined(Type attributeType, bool inherit);
21: }
ControllerDescriptor實現了ICustomAttributeProvider接口,意味著我們可 以通過調用GetCustomAttributes和GetCustomAttributes方法獲取應用在 Controller類型上的所有自定義特性或者給定類型的特性,也可以調用IsDefined 方法判斷指定的自定義特性類型是否應用在對應的Controller類型上。
另一個方法GetFilterAttributes用於獲取應用在Controller上的所有篩選器 特性(繼承自抽象類FilterAttribute)。篩選器是一種基於AOP的設計,它使我 們可以一些基於橫切關注點相關邏輯的執行動態的注入到Action方法的執行前後 ,我們會在“Action方法的執行”中對篩選器進行詳細地介紹。
ControllerDescriptor的FindAction方法根據指定的Controller上下文和名稱 得到相應的Action方法,返回的是用於描述Action方法的ActionDescriptor對象 。而GetCanonicalActions得到當前Controller的所有Action方法,返回類型為 ActionDescriptor數組。
二、ReflectedControllerDescriptor
在ASP.NET MVC應用編程接口中定義了抽象類ControllerDescriptor的唯一繼 承類型ReflectedControllerDescriptor。顧名思義, ReflectedControllerDescriptor通過反射的機制解析用於描述Controller的元數 據。如下面的代碼片斷所示,表示Controller類型的ControllerType屬性在構造 函數中指定。ReflectedControllerDescriptor通過反射的方式獲取應用在 Controller類型上的相關特性以提供針對ICustomAttributeProvider接口的實現 。
1: public class ReflectedControllerDescriptor : ControllerDescriptor
2: {
3: public ReflectedControllerDescriptor(Type controllerType);
4:
5: public override object[] GetCustomAttributes(bool inherit);
6: public override object[] GetCustomAttributes(Type attributeType, bool inherit);
7: public override IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache);
8: public override bool IsDefined(Type attributeType, bool inherit);
9:
10: public override ActionDescriptor FindAction( ControllerContext controllerContext, string actionName);
11: public override ActionDescriptor[] GetCanonicalActions();
12:
13: public sealed override Type ControllerType { get; }
14: }