看mvc的源码我们知道,它是在 ControllerActionInvoker 类中执行 InvokeAction 方法来实现过滤器和action方法执行的。
通过查看源码我们知道,他是通过调用 InvokeActionMethodWithFilters 方法来实现IActionFilter过滤器和action方法执行的,如图
点进去这个方法我们可以看到
1 protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) 2 { 3 ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters); 4 Func<ActionExecutedContext> seed = () => new ActionExecutedContext(controllerContext, actionDescriptor, false, null) 5 { 6 Result = this.InvokeActionMethod(controllerContext, actionDescriptor, parameters) 7 }; 8 return filters.Reverse<IActionFilter>().Aggregate(seed, (Func<ActionExecutedContext> next, IActionFilter filter) => () => ControllerActionInvoker.InvokeActionMethodFilter(filter, preContext, next))(); 9 }
看到这里我直接懵逼了,由于它委托中嵌套了委托而且还简写,还调用了扩展方法Aggregate累加器,所以很难直接看懂,这到底是怎么执行代码的呐?我来把代码整理如下
1 public class Class1 2 { 3 4 protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) 5 { 6 ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters); 7 8 Func<ActionExecutedContext> seed = () => new ActionExecutedContext(controllerContext, actionDescriptor, false, null) 9 { 10 Result = this.InvokeActionMethod(controllerContext, actionDescriptor, parameters) 11 }; 12 13 Func<Func<ActionExecutedContext>, IActionFilter, Func<ActionExecutedContext>> secondParam = 14 (Func<ActionExecutedContext> next, IActionFilter filter) => 15 { 16 Func<ActionExecutedContext> returnFunc = () => 17 { 18 return Class1.InvokeActionMethodFilter(filter, preContext, next); 19 }; 20 21 return returnFunc; 22 23 //这个是简写 24 //return () => Class1.InvokeActionMethodFilter(filter, preContext, next); 25 }; 26 27 return filters.Reverse<IActionFilter>().Aggregate(seed, 28 //(Func<ActionExecutedContext> next, IActionFilter filter) => () => Class1.InvokeActionMethodFilter(filter, preContext, next) 29 secondParam 30 ) 31 .Invoke(); 32 } 33 34 internal static ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func<ActionExecutedContext> continuation) 35 { 36 filter.OnActionExecuting(preContext); 37 if (preContext.Result != null) 38 { 39 return new ActionExecutedContext(preContext, preContext.ActionDescriptor, true, null) 40 { 41 Result = preContext.Result 42 }; 43 } 44 bool flag = false; 45 ActionExecutedContext actionExecutedContext = null; 46 try 47 { 48 actionExecutedContext = continuation(); 49 } 50 catch (ThreadAbortException) 51 { 52 actionExecutedContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false, null); 53 filter.OnActionExecuted(