ASP.NET MVC 过滤器(三)

ASP.NET MVC 过滤器(三)

前言

本篇讲解行为过滤器的执行过程,过滤器实现、使用方式有AOP的意思,可以通过学习了解过滤器在框架中的执行过程从而获得一些AOP方面的知识(在顺序执行的过程中,这种编程模式就是横向的插入点),言归正传,我们还是以学习过滤器为主。对于IAuthorizationFilter授权认证过滤器的使用篇幅,我知道怎么用但是写不出来,里面包含知识点很多,功底尚浅写了一半又给删掉了,宁愿不发也不能坑人,在后面的学习中假使我可以掌握了,一定会及时的写出来跟大家分享。这个目录也空在这也算是给自己的一个提醒吧。

ASP.NET MVC过滤器

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

IActionFilter行为过滤器的执行过程

我们直接进入主题,这里的执行过程还是接着过滤器(一)中的部分,我们看下执行过程的示意图:

图1

如图1所示,就是整个的一个执行过程,图太大拆开来看,这样比较细致一点(这里捎带一句,后面许多部分的内容都都包含在这个示意图里,比如说Model元数据、Model绑定和Model验证)。

图2

首先是调用了ControllerActionInvoker类型的GetParameterValues()方法,GetParameterValues()方法的参数是控制器上下文参数对象【ControllerContext类型】和控制器方法描述对象【ActionDescriptor类型】,然后在此方法中会根据ActionDescriptor类型的参数来调用GetParameters()方法获取到控制器方法参数的描述对象【ParameterDescriptor类型】的集合,这里对ParameterDescriptor类型不做过多的讲解,只需了解它是包含了控制器方法参数的一些信息,比如说参数名称、参数类型等等。

图3

从图2中所示的那样,获取到了ParameterDescriptor类型的集合后,便会遍历此集合并且调用图3中所示的ControllerActionInvoker类型的GetParameterValue()方法【这里注意一下跟上面的图2所示的方法是不同的】,调用GetParameterValue()方法的目的是生成一个键值队类型的对象【红色箭头所指】,键值队中的键表示参数名称,值则为参数的值,而生成的过程是:首先MVC框架会调用用户自定义的模型绑定器(如果有自定义的)【实现了IModelBinder接口的类型】,并且调用自定义模型绑定器的方法以此来获取控制器方法参数的参数值,如果没有发现自定义的模型绑定器,则会调用默认的Model绑定器进行参数绑定,如果没有匹配的类型返回一个默认值ParameterDescriptor.DefaultValue】。(关于Model绑定器内容后续系列会有讲解)

图4

有了参数值信息的键值队过后,接着调用ControllerActionInvoker类型的InvokeActionMethodWithFilters()方法,在此方法会生成两种参数类型以便由ControllerActionInvoker类型的InvokeActionMethodFilter()方法调用,下面我们先讲解这两种参数类型:

  1. ActionExecutingContext
  2. Func<ActionExecutedContext>

第一个参数

1 public class ActionExecutingContext : ControllerContext
2 {
3 public ActionExecutingContext();
4 public ActionExecutingContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> actionParameters);
5
6 public virtual ActionDescriptor ActionDescriptor { get; set; }
7 public virtual IDictionary<string, object> ActionParameters { get; set; }
8 public ActionResult Result { get; set; }
9 }

在上面类型的定义中,我们了解到ActionExecutingContext类型继承至ControllerContext类型,并且包含着一些信息的引用,这便是可以在控制器方法执行之前执行自己的一些自定义操作。

第二个参数

 1     public class ActionExecutedContext : ControllerContext
2 {
3
4 public ActionExecutedContext();
5 public ActionExecutedContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, bool canceled, Exception exception);
6
7 public virtual ActionDescriptor ActionDescriptor { get; set; }
8 public virtual bool Canceled { get; set; }
9 public virtual Exception Exception { get; set; }
10 public bool ExceptionHandled { get; set; }
11 public ActionResult Result { get; set; }
12 }

ActionExecutedContext类型跟ActionExecutingContext类型的区别在于前者多了两个属性一个是用于保存异常信息的,另一个属性是用来设置是否处理了异常,这个会在异常过滤器篇幅中讲解。

切回主题,大概知道这两种类型的定义就行了,说到Func<ActionExecutedContext>类型的参数,在MVC框架中默认的设置了Lambda表达式,并且对返回类型中的Result属性又设置了一个表达式调用的是ControllerActionInvoker类型的InvokeActionMethod()方法,这个方法后面会讲到。我们看一下表达式的定义,不然有点混乱:

1 Func<ActionExecutedContext> seed = () =>
2 {
3 new ActionExecutedContext(controllerContext,actionDescriptor, false,null)
4 {
5 Result = this.InvokeActionMethod(controllerContext, actionDescriptor, parameters)
6 }
7 };

上述的这些参数都准备完毕后,可以调用执行最后的ControllerActionInvoker类型的InvokeActionMethodFilter()方法,而其中的IActionFilter类型的参数则有在前面篇幅中讲到的FilterInfo类型中的ActionFilters属性提供,并且是遍历执行的,最后可以看到在InvokeActionMethodFilter()方法的内部首先是由IActionFilter类型的参数调用了OnActionExecuting()方法,然后执行Func<ActionExecutedContext>类型的参数,因为上面说到的,这个委托类型的参数已经定义好了默认的执行方式,是执行ControllerActionInvoker类型的中的InvokeActionMethod()方法,在此方法执行后在执行IActionFilter类型的OnActionExecuted()方法,并且最终的结果值返回到了ActionExecutedContext类型的Result属性中。

最后我们看一下IActionFilter类型的结构定义:

 1     public interface IActionFilter
2 {
3 // 摘要:
4 // 在执行操作方法后调用。
5 //
6 // 参数:
7 // filterContext:
8 // 筛选器上下文。
9 void OnActionExecuted(ActionExecutedContext filterContext);
10 //
11 // 摘要:
12 // 在执行操作方法之前调用。
13 //
14 // 参数:
15 // filterContext:
16 // 筛选器上下文。
17 void OnActionExecuting(ActionExecutingContext filterContext);
18 }

行为过滤器大概的执行过程讲解完毕了,下一篇会对这种类型的过滤器的应用作大概讲解。

作者:金源

出处:http://www.cnblogs.com/jin-yuan/

MVC 过滤器3的更多相关文章

  1. mvc过滤器学习(1)

    mvc 过滤器结构图 AuthorizeAttribute AuthorizeAttribute是IAuthorizationFilter的默认实现,添加了Authorize特性的Action将对用户 ...

  2. ASP.NET MVC 过滤器(一)

    ASP.NET MVC 过滤器(一) 前言 前面的篇幅中,了解到了控制器的生成的过程以及在生成的过程中的各种注入点,按照常理来说篇幅应该到了讲解控制器内部的执行过程以及模型绑定.验证这些知识了.但是呢 ...

  3. ASP.NET MVC 过滤器(三)

    ASP.NET MVC 过滤器(三) 前言 本篇讲解行为过滤器的执行过程,过滤器实现.使用方式有AOP的意思,可以通过学习了解过滤器在框架中的执行过程从而获得一些AOP方面的知识(在顺序执行的过程中, ...

  4. ASP.NET MVC 过滤器(四)

    ASP.NET MVC 过滤器(四) 前言 前一篇对IActionFilter方法执行过滤器在框架中的执行过程做了大概的描述,本篇将会对IActionFilter类型的过滤器使用来做一些介绍. ASP ...

  5. ASP.NET MVC 过滤器(五)

    ASP.NET MVC 过滤器(五) 前言 上篇对了行为过滤器的使用做了讲解,如果在控制器行为的执行中遇到了异常怎么办呢?没关系,还好框架给我们提供了异常过滤器,在本篇中将会对异常过滤器的使用做一个大 ...

  6. asp.net MVC 过滤器使用案例:统一处理异常顺道精简代码

    重构的乐趣在于精简代码,模块化设计,解耦功能……而对异常处理的重构则刚好满足上述三个方面,下面是我的一点小心得. 一.相关的学习 在文章<精简自己20%的代码>中,讨论了异常的统一处理,并 ...

  7. MVC过滤器详解

    MVC过滤器详解   APS.NET MVC中(以下简称"MVC")的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理. ...

  8. MVC过滤器使用案例:统一处理异常顺道精简代码

    重构的乐趣在于精简代码,模块化设计,解耦功能……而对异常处理的重构则刚好满足上述三个方面,下面是我的一点小心得. 一.相关的学习 在文章<精简自己20%的代码>中,讨论了异常的统一处理,并 ...

  9. ASP.NET MVC 过滤器详解

    http://www.fwqtg.net/asp-net-mvc-%E8%BF%87%E6%BB%A4%E5%99%A8%E8%AF%A6%E8%A7%A3.html 我经历了过滤器的苦难,我想到了还 ...

  10. ASP.NET MVC过滤器(一)

    MVC过滤器是加在 Controller 或 Action 上的一种 Attribute,通过过滤器,MVC 网站在处理用户请求时,可以处理一些附加的操作,如:用户权限验证.系统日志.异常处理.缓存等 ...

随机推荐

  1. MVC 定义JsonpResult实现跨域请求

    MVC 定义JsonpResult实现跨域请求 1:原理 在js中,XMLHttpRequest是不能请求不同域的数据,但是script标签却可以,所以可以用script标签实现跨域请求.具体是定义一 ...

  2. SQL_sql的简单查询

    ***********************************************声明*************************************************** ...

  3. 设计模式C++实现_1_Singleton设计模式(简单的实现)

    Singleton设计模式 思路如以下: Single.h #pragma once #include <iostream> #include <string> using n ...

  4. Python 目录操作(转)

    在Python中,文件操作主要来自os模块,主要方法如下: os.listdir(dirname):列出dirname下的目录和文件os.getcwd():获得当前工作目录os.curdir:返回当前 ...

  5. Dos命令将合并两个文本文件的内容

    当生产线的问题,有一个放b.txt的内容被添加到a.txt这需要采取.在考虑这个问题.我的第一感觉是敲代码.阅读b.txt内容,渐进写a.txt.想起昨天在加工处理生产线600M决的方法,我用java ...

  6. javascript系列之DOM(二)

    原文:javascript系列之DOM(二) 原生DOM扩展 我们接着第一部分来说,上文提到了两种常规的DOM操作:创建文档片段和遍历元素节点.我们知道那些雨后春笋般的库,有很大一部分工作就是提供了一 ...

  7. .Net常用方法汇总

    //创建某个目录的文件夹 调用如下: var folder = initFolder(Export_Folder.Text, "ExportMembers"); private s ...

  8. Android学习----异常(2):Please ensure that adb is correctly located at &#39; ... &#39;

    打开任务管理器,在后台进程中找到 kadb,结束这个进程,重新启动eclipse.

  9. 从头开始学JavaScript (九)——执行环境和作用域

    原文:从头开始学JavaScript (九)--执行环境和作用域 一.执行环境:定义了变量或者函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有与之关联的变量对象. 变量对象:保存着环境中 ...

  10. CocoaPods 建立私有仓库

    CocoaPods是iOS,Mac下优秀的第三方包管理工具,类似于java的maven,给我们项目管理带来了极大的方便. [个人或公司在开发过程中,会积累很多可以复用的代码包,有些我们不想开源,又想像 ...