前面的篇幅中,了解到了控制器的生成的过程以及在生成的过程当中的各类注入点,依照常理来讲篇幅应该到了解说控制器内部的运行过程以及模型绑定、验证这些知识了。html
但是呢,在MVC框架中提供了一种机制在控制器方法运行以前咱们还可以经过这样的机制来作一些横向切面的操做,这样的机制的实现就是过滤器了。在本篇和兴许的篇幅中将会对几种过滤器作一番解说,并且会对过滤器在框架中的一个运行过程进行粗略的解说。编程
咱们在得到控制器工厂生成的控制器后。运行某些控制器行为以前。老是要验证一些数据或者是请求信息什么的。这里就要用到过滤器的机制了,而在框架中过滤器是怎么运转的,经过本小节的学习会让你有个大概的了解。框架
现在咱们切入主题来解说一下在MVC框架中的过滤器。ide
图1函数
如上图所看到的的这样,在控制器运行的时候会调用ControllerActionInvoker类型的InvokeAction()方法,而在InvokeAction()方法中,框架会默认的生成控制器描写叙述对象ControllerDescriptor和控制器行为描写叙述对象ActionDescriptor。这两种类型的对象都是对当前的控制器和所要请求的控制器方法信息的封装,这个知识点咱们会在兴许的篇幅中讲到,这里仅仅须了解一下,忽略它们的生成过程。參照例如如下图:工具
图2post
依照InvokeAction()方法的运行流程,到了生成FilterInfo类型的时候,咱们都知道MVC框架给咱们提供了四种过滤器,哪四种后面一一介绍,那么FilterInfo类型是干什么的呢?来看一下它的对象结构:学习
1 //封装有关可用的操做筛选器的信息。2 public class FilterInfo 3 { 4 public FilterInfo(); 5 public FilterInfo(IEnumerable<Filter> filters); 6 public IList<IActionFilter> ActionFilters { get; } 7 public IList<IAuthorizationFilter> AuthorizationFilters { get; } 8 public IList<IExceptionFilter> ExceptionFilters { get; } 9 public IList<IResultFilter> ResultFilters { get; } 10 }spa
它的内部有着四种过滤器集合类型的属性,并且有个构造函数是接收IEnumerable<Filter>类型的。当FilterInfo类型在初始化的时候会依据构造函数传入的类型进行解析,并且对四个属性分别赋值,这就要涉及到还有一个元数据描写叙述对象Filter了。.net
咱们来看一下Filter对象的结构:
1 // 表示一个元数据类。它包括对一个或多个筛选器接口的实现、筛选器顺序和筛选器范围的引用。 2 public class Filter 3 { 4 public const int DefaultOrder = -1; 5 public Filter(object instance, FilterScope scope, int? order); 6 7 public object Instance { get; protected set; } 8 public int Order { get; protected set; } 9 public FilterScope Scope { get; protected set; } 10 }
看到这里有可能有的朋友不明确这个对象。详细怎么表示?因为元数据编程模式很是少见,这里我给你们举个样例。一看就明确了:
1 [Authorize(Order=1)] 2 public class DemoController : Controller 3 { 4 …… 5 }
上面的这个列子则会在系统生成的时候生成一个Filter类型的对象。并且赋值Order等于1,而Filter类型中的Instance属性则是对上述样例中的Authorize类型实例引用。这就是元数据描写叙述对象,固然了讲的不是太详细,能让你们明确便可了,Authorize类型的详细使用在下一篇中会有讲到。
现在咱们回归主题。如图2中所表示的那样。IEnumerable<Filter>集合类型是关键。那么怎么生成IEnumerable<Filter>集合类型?
先是调用ControllerActionInvoker类型中的GetFilters()方法,咱们看到方法的參数类型为控制器參数上下文对象和控制器行为元数据描写叙述对象,这两个对象就够了,它们中包括的信息已经很是多了,在ControllerActionInvoker的GetFilters()方法内部调用FilterProviderCollection类型的GetFilters()。和上面所述的类型方法签名同样,仅仅只是返回类型有差别而已。而真正的依据參数运行生成Filter类型的对象是实现了IFilterProvider类型的对象。
看一下IFilterProvider类型的结构:
1 // 提供用于查找筛选器的接口。2 public interface IFilterProvider 3 { 4 IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor); 5 }
而这个对象是可以从外部注入进来的。在控制器(三)中提到过的。经过实现IDependencyResolver类型,而在框架中也会默认的实现一个(仅仅是我经过反编译工具没看到,显示的是错误信息。表示很是郁闷,后文中就叫它为默认实现)。在FilterProviderCollection类型的GetFilters()中,会经过默认实现来获得当前请求的行为上的所有过滤器元数据描写叙述对象,并且进行排序、验证。这里就很少叙述了。而后返回IEnumerable<Filter>集合类型并且生成FilterInfo类型的对象。
图3
先来看一下IAuthorizationFilter类型的定义:
1 public interface IAuthorizationFilter 2 { 3 // 摘要: 4 // 在需要受权时调用。5 // 6 // 參数: 7 // filterContext: 8 // 筛选器上下文。 9 void OnAuthorization(AuthorizationContext filterContext); 10 }
看到如上的定义。再看图3IAuthorizationFilter类型的运行过程一目了然,依据ControllerContext控制器參数上下文对象和控制器行为据描写叙述对象actionDescriptor生成AuthorizationContext受权认证过滤器參数上下文对象,并且会遍历FilterInfo类型中的AuthorizationFilters属性,挨个的去运行咱们定义的过滤器。
本篇的内容就说到这里。下个篇幅中会讲到IAuthorizationFilter类型的使用
做者:金源
出处:http://blog.csdn.net/jinyuan0829
本文版权归做者和CSDN共同拥有,欢迎转载,但未经做者容许必须保留此段声明,且在文章页面