我们用筛选器控制Action运行前后需要处理的事情
public abstract class ActionFilterTestcs:FilterAttribute,IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{ }
public void OnActionExecuting(ActionExecutingContext filterContext)
{ }
}
抽象一个ActionFilterTestcs
在Controller中比如HomeController中继承此抽象类
public class FooAttribute:ActionFilterTestcs
{
int a = 1;
}
在Action Index上面用上这两个筛选类如下:
[Bar]
[Foo]
public ActionResult Index()
{ return View();}
Filter 执行过程从 BeginInvokeActionMethodWithFilters开始
protected internal virtual IAsyncResult BeginInvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state)
{
Func<ActionExecutedContext> endContinuation = null;
BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState)
{
ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
AsyncResult innerAsyncResult = null;
Func<Func<ActionExecutedContext>> beginContinuation = () => {
innerAsyncResult = BeginInvokeActionMethod(controllerContext, actionDescriptor, parameters, asyncCallback, asyncState);
return () =>
new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */)
{
Result = EndInvokeActionMethod(innerAsyncResult)
};
}; // need to reverse the filter list because the continuations are built up backward
Func<Func<ActionExecutedContext>> thunk = filters.Reverse().Aggregate(beginContinuation,
(next, filter) => () => InvokeActionMethodFilterAsynchronously(filter, preContext, next));
endContinuation = thunk();
if (innerAsyncResult != null)
{ // we're just waiting for the inner result to complete
return innerAsyncResult;
}
else
{ // something was short-circuited and the action was not called, so this was a synchronous operation
SimpleAsyncResult newAsyncResult = new SimpleAsyncResult(asyncState);
newAsyncResult.MarkCompleted(true /* completedSynchronously */, asyncCallback);
return newAsyncResult;
}
};
EndInvokeDelegate<ActionExecutedContext> endDelegate = delegate(IAsyncResult asyncResult)
{
return endContinuation();
};
return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionMethodWithFiltersTag);
}
通过 Aggregate构建了一个Action筛选器(IList<IActionFilter>)递归链表endContinuation = thunk();是这个链表的开始执行地方。
具体过程 Filter1,beginContinuation 返回结果为Aggregate累加。MVC5的ActionFilter链表递归结构跟MVC3,4 有一定的区别,前者BeginInvokeActionMethodWithFilters返回的是Func<Func<ActionExecutedContext>>,后者直接Func<ActionExecutedContext>。
而执行过程,OnActionExecuted则是延缓了执行,从Func<Func<ActionExecutedContext>>到 Func<ActionExecutedContext>他通过了递归经过了一层剥离方法然后再执行OnActionExecuted执行过程为 :
Filter1.OnActionExecuting-》Filter2.OnActionExecuting-》-》Filter3.OnActionExecuting-》BeginInvokeActionMethod-》EndInvokeActionMethod-》Filter1.OnActionExecuted-》Filter2.OnActionExecuted-》Filter2.OnActionExecuted
MVC3,4执行过程为:Filter1.OnActionExecuting-》Filter2.OnActionExecuting-》-》Filter3.OnActionExecuting-》InvokeActionMethodFilter-》Filter3.OnActionExecuted-》Filter2.OnActionExecuted-》Filter1.OnActionExecuted