Asp.net MVC源码分析 -- Filter 以及调用优先级
在Asp.net MVC 框架中一共有四种型的Filter,它们分别是
1.IActionFilter
2.IAuthorizationFilter
3.IExceptionFilter
4.IResultFilter
别外再加上一个GlobalFilters.Filters全局的,看起来挺多但是基本上这些Filter都与Action的调用有关,
让我沿着Mvc3.0源码一一找出它们的线索。
首先让我们看FilterProviders.cs,这是一个全局的系统默认FilterFilter provider,当然们也可以向里面加自定义的provider.
FilterProviders.cs
1 namespace System.Web.Mvc {
2 public static class FilterProviders {
3 static FilterProviders() {
4 Providers = new FilterProviderCollection();
5 Providers.Add(GlobalFilters.Filters);
6 Providers.Add(new FilterAttributeFilterProvider());
7 Providers.Add(new ControllerInstanceFilterProvider());
8 }
9
10 public static FilterProviderCollection Providers {
11 get;
12 private set;
13 }
14 }
15 }
这里面最为重要的是FilterAttributeFilterProvider,它提供了找出Action所有在元数据中Filter的功能方法。
FilterAttributeFilterProvider.cs
1 public class FilterAttributeFilterProvider : IFilterProvider {
2 private readonly bool _cacheAttributeInstances;
3
4 public FilterAttributeFilterProvider()
5 : this(true) {
6 }
7
8 public FilterAttributeFilterProvider(bool cacheAttributeInstances) {
9 _cacheAttributeInstances = cacheAttributeInstances;
10 }
11
12 protected virtual IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
13 return actionDescriptor.GetFilterAttributes(_cacheAttributeInstances);
14 }
15
16 protected virtual IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
17 return actionDescriptor.ControllerDescriptor.GetFilterAttributes(_cacheAttributeInstances);
18 }
19
20 public virtual IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
21 ControllerBase controller = controllerContext.Controller;
22 if (controller == null) {
23 return Enumerable.Empty<Filter>();
24 }
25
26 var typeFilters = GetControllerAttributes(controllerContext, actionDescriptor)
27 .Select(attr => new Filter(attr, FilterScope.Controller, null));
28 var methodFilters = GetActionAttributes(controllerContext, actionDescriptor)
29 .Select(attr => new Filter(attr, FilterScope.Action, null));
30
31 return typeFilters.Concat(methodFilters).ToList();
32 }
33 }
-------------------------------------------------------------------------------------------------
接下来我们看Mvm框架是如何获取和使用这些Filter的:
ControllerActionInvoker.cs
1 public virtual bool InvokeAction(ControllerContext controllerContext, string actionName) {
2 if (controllerContext == null) {
3 throw new ArgumentNullException("controllerContext");
4 }
5 if (String.IsNullOrEmpty(actionName)) {
6 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
7 }
8
9 ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext);
10 ActionDescriptor actionDescriptor = FindAction(controllerContext, controllerDescriptor, actionName);
11 if (actionDescriptor != null) {
12 FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
13
14 try {
15 AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
16 if (authContext.Result != null) {
17 // the auth
补充:Web开发 , ASP.Net ,