前面的篇幅中,了解到了控制器的生成的过程以及在生成的过程当中的各类注入点,按照常理来讲篇幅应该到了讲解控制器内部的执行过程以及模型绑定、验证这些知识了。可是呢,在MVC框架中提供了一种机制在控制器方法执行以前咱们还能够经过这种机制来作一些横向切面的操做,这种机制的实现就是过滤器了,在本篇和后续的篇幅中将会对几种过滤器作一番讲解,而且会对过滤器在框架中的一个执行过程进行粗略的讲解。编程
过滤器在系统框架中的总体对象模型c#
IAuthorizationFilter受权认证过滤器的执行过程框架
使用IAuthorizationFilter过滤器ide
IActionFilter行为过滤器的执行过程函数
自定义实现IActionFilter行为过滤器工具
异常过滤器的使用学习
咱们在得到控制器工厂生成的控制器后,执行某些控制器行为以前,老是要验证一些数据或者是请求信息什么的,这里就要用到过滤器的机制了,而在框架中过滤器是怎么运转的,经过本小节的学习会让你有个大概的了解。spa
如今咱们切入主题来说解一下在MVC框架中的过滤器。对象
图1排序
如上图所示的这样,在控制器执行的时候会调用ControllerActionInvoker类型的InvokeAction()方法,而在InvokeAction()方法中,框架会默认的生成控制器描述对象ControllerDescriptor和控制器行为描述对象ActionDescriptor,这两种类型的对象都是对当前的控制器和所要请求的控制器方法信息的封装,这个知识点咱们会在后续的篇幅中讲到,这里只须了解一下,忽略它们的生成过程。参照以下图:
图2
按照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 }
它的内部有着四种过滤器集合类型的属性,而且有个构造函数是接收IEnumerable<Filter>类型的,当FilterInfo类型在初始化的时候会根据构造函数传入的类型进行解析,而且对四个属性分别赋值,这就要涉及到另外一个元数据描述对象Filter了。
咱们来看一下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类型的使用