ASP.NET MVC 过滤器(一)

 ASP.NET MVC 过滤器(一)

前言

前面的篇幅中,了解到了控制器的生成的过程以及在生成的过程中的各种注入点,依照常理来说篇幅应该到了解说控制器内部的运行过程以及模型绑定、验证这些知识了。

可是呢,在MVC框架中提供了一种机制在控制器方法运行之前我们还能够通过这样的机制来做一些横向切面的操作,这样的机制的实现就是过滤器了。在本篇和兴许的篇幅中将会对几种过滤器做一番解说,而且会对过滤器在框架中的一个运行过程进行粗略的解说。

 

ASP.NET MVC过滤器

  •   过滤器在系统框架中的总体对象模型
  •   IAuthorizationFilter授权认证过滤器的运行过程
  •   使用IAuthorizationFilter过滤器
  •   IActionFilter行为过滤器的运行过程
  •   自己定义实现IActionFilter行为过滤器
  •   异常过滤器的使用

 

过滤器在系统框架中的总体对象模型

我们在获得控制器工厂生成的控制器后。运行某些控制器行为之前。总是要验证一些数据或者是请求信息什么的。这里就要用到过滤器的机制了,而在框架中过滤器是怎么运转的,通过本小节的学习会让你有个大概的了解。

如今我们切入主题来解说一下在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类型的对象。

 

IAuthorizationFilter授权认证过滤器的运行过程

图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类型的使用

 

 

 

作者:金源

posted on 2018-03-21 04:46  yjbjingcha  阅读(357)  评论(0编辑  收藏  举报

导航