有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你创建action过滤器。Action过滤器是自定义的Attributes,用来标记添加Action方法之前或者Action方法之后的行为到控制器类中的Action方法中。

一些可能用到Action过滤器的地方有:

  • 日志,异常处理
  • 身份验证和授权 - 限制用户的访问
  • 输出缓存 - 保存一个Action的结果
  • 网络爬虫的过滤
  • 本地化
  • 动态Action - 将一个Action注入到控制器中

ASP.NET MVC为我们提供了下面的几个Filter接口:

    • IActionFilter
    • IAuthorizationFilter
    • IExceptionFilter
    • IResultFilter

      要实现一个Filter,我们需要继承自FilterAttribute类同时实现上面的一个或几个接口:

      public class MyFilter : FilterAttribute, IActionFilter, IResultFilter
      {

      这几个接口提供的方法如下:

      上图的方法和Filter接口对应的方法按名称对号入座就可以。

      IActionFilter接口有两个方法:

      其中OnActionExecuting在执行Action方法之前会被调用,OnActionExecuted会在Action方法执行后调用。注意他们的参数分别是ActionExecutingContext和ActionExecutedContext。

      ActionExecutedContext类包含一个 Canceled的属性,允许你取消当前的Action(怎么原来在P3中是在ActionExecutingContext的Canceled属性在P5中没有了呢?神奇.那么在OnActionExecuting的时候怎么取消一个Action呢?)。

      FilterExcutedContext 类包含一个Exception属性和一个ExceptionHandled属性。如果Exception属性为null,则没有异常在action stack中,表明Action方法运行并没有发生错误。反之则为出现异常。如果将ExceptionHandled属性设置为true则表明在这个Filter中已经处理了异常。

      IResultFilter接口也提供了两个方法:

      他们分别在Action返回结果(例如return View();)之前和之后执行。和IActionFilter差不多就不多说了。

      IAuthorizationFilter是一个用于身份验证的Filter。只提供了一个void OnAuthorization(AuthorizationContext filterContext)方法。

      IExceptionFilter会在出现异常的时候调用,也是只 提供一个void OnException(ExceptionContext filterContext)的方法;

      这些Filter可以被应用在类或者方法上,下面我们来看一下他们的执行顺序。首先我们写一个BaseController并加上两个Filter:

      [MyFilter2(Target = "BaseController")]
      [MyFilter1(Target="BaseController")]
      public class BaseController : Controller

      应为Controller类是实现这几个Filter接口的,所以我们在HomeController中重写Controller基类中的所有Filter接口的方法,并在HomeController类和里面的Filter方法加上我们自定义的MyFilter:

      [MyFilter2(Target = "HomeController")]
      //[MyFilter1(Target = "HomeController")]//注意我在这里把MyFilter1注释了.
      [HandleError]
      public class HomeController : BaseController
      {
          [MyFilter2(Target = "HomeController.Filter")]
          [MyFilter1(Target = "HomeController.Filter")]
          public ActionResult Filter()
          {
              return Content("<div>这是在Action方法里面返回的内容!</div>");
          }      protected override void OnActionExecuted(ActionExecutedContext filterContext)
          {
              filterContext.HttpContext.Response.Write("<div>这是在HomeController里面重写OnActionExecuted方法添加的内容!</div>");
          }      protected override void OnActionExecuting(ActionExecutingContext filterContext)
          {
              filterContext.HttpContext.Response.Write("<div>这是在HomeController里面重写OnActionExecuting方法添加的内容!</div>");
          }      protected override void OnAuthorization(AuthorizationContext filterContext)
          {
              filterContext.HttpContext.Response.Write("<div>这是在HomeController里面重写OnAuthorization方法添加的内容!</div>");
          }      protected override void OnException(ExceptionContext filterContext)
          {
              filterContext.HttpContext.Response.Write("<div>这是在HomeController里面重写OnException方法添加的内容!</div>");
              filterContext.ExceptionHandled = true;
          }      protected override void OnResultExecuted(ResultExecutedContext filterContext)
          {
              filterContext.HttpContext.Response.Write("<div>这是在HomeController里面重写OnResultExecuted方法添加的内容!</div>");
          }      protected override void OnResultExecuting(ResultExecutingContext filterContext)
          {
              filterContext.HttpContext.Response.Write("<div>这是在HomeController里面重写OnResultExecuting方法添加的内容!</div>");
          }

      然后我们运行一下看看结果如何:

      从运行结果我们可以看到,在Controller中重写的Filter会最先执行,然后到应用在类上的Filter,然后再到应用在类方法上的Filter。

      而4个接口的方法执行顺序如下:IAuthorizationFilter -> IActionFilter -> IResultFilter -> IExceptionFilter .

      而对于同一个Filter,例如IAuthorizationFilter在MyFilter1和MyFilter2里里面的实现,又根据他们的加载顺序不同而不同。

      在BaseController中应用的Filter会被子类继承,如果子类又应用了和基类同样的Filter,则会不执行基类的Filter。例如上面的HomeController应用了MyFilter2,所以调用HomeController的MyFilter2,而不是BaseController的MyFilter2。

      这个执行顺序还得大家好好研究才能了解的。

      同时FilterAttribute还提供了一个Order的属性,用于指定Filter的执行顺序。

      每一个Action过滤器都有一个 Order 属性,用来决定Action过滤器在该范围内的执行顺序。Order属性必需是0(默认值)或者更大的整数值。省略Order属性则会给该过滤器的Order值为 -1, 表明未指明顺序。任何一个在同一范围的Action过滤器Order设为 -1 的都将按不确定的顺序执行,但在此之前过滤器有一个特定的顺序(请参考上图).

      当设置Order属性的值的时候,必需指定一个唯一的值。如果两个或者更多的Action过滤器具有相同的Order属性值,将会抛出一个异常。

      来看一个示例:

      
      [Filter1(Order = 2)]
      [Filter2(Order = 3)]
      [Filter3(Order = 1)]
      public void Index()
      {
          RenderView("Index");

      Filter的执行顺序为:Filter3 => Filter1 => Filter2.

      暂时就写这么多吧,这一部分主要介绍概念。Enjoy!Post by Q.Lee.lulu

      本文的Blog程序示例代码: ActionFilter.rar

[转]ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍)的更多相关文章

  1. ASP.NET MVC 入门10、Action Filter 与 内置的Filter实现(实例-防盗链)

    于ASP.NET MVC Preview5. 前一篇中我们已经了解了Action Filter 与 内置的Filter实现,现在我们就来写一个实例.就写一个防盗链的Filter吧. 首先继承自Filt ...

  2. [转]ASP.NET MVC 入门10、Action Filter 与 内置的Filter实现(实例-防盗链)

    前一篇中我们已经了解了Action Filter 与 内置的Filter实现,现在我们就来写一个实例.就写一个防盗链的Filter吧. 首先继承自FilterAttribute类同时实现IAction ...

  3. ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍)

    原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/09/1307660.html 有时候你想在调用action方法之前或者action方法之后处 ...

  4. ASP.NET MVC 入门系列教程

    ASP.NET MVC 入门系列教程 博客园ASP.NET MVC 技术专题 http://kb.cnblogs.com/zt/mvc/ 一个居于ASP.NET MVC Beta的系列入门文章,有朋友 ...

  5. 10、ASP.NET MVC入门到精通——Model(模型)和验证

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 模型就是处理业务,想要保存.创建.更新.删除的对象. 注解(通过特性实现) DisplayName Required StringLengt ...

  6. ASP.NET MVC 入门8、ModelState与数据验证

    原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/08/1305962.html ViewData有一个ModelState的属性,这是一个类型 ...

  7. ASP.NET MVC内置的Filter实现介绍

    有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你创建action过滤器.Action过滤器是自定义的Attributes,用来标记添 ...

  8. [转]ASP.NET MVC 入门8、ModelState与数据验证

    ViewData有一个ModelState的属性,这是一个类型为ModelStateDictionary的ModelState类型的字典集合.在进行数据验证的时候这个属性是比较有用的.在使用Html. ...

  9. ASP.NET MVC 入门

    ASP.NET MVC 入门 (Learning ASP.NET MVC) 传统的WebForm发展到如今出现不少的缺陷, 比如为了解决Http的无状态WebForm模式使用了ViewsState来保 ...

随机推荐

  1. ios中XPath的语法

    在XML的读写中,我们知道有Xpath的语法 1.定位节点:(/)代表绝对的路径,代表起始地位置.(//)表示文件中所有符合模式的元素都会被选出来,即使是处于树中不同的层级也会被选出来 2.KissX ...

  2. Newtonsoft.Json.dll反序列化JSON字符串的方法

      1.直接反序列化JSON字符串 //引用序列化.反序列化JSON字符串用到的空间 using Newtonsoft.Json; using Newtonsoft.Json.Linq; //定义一个 ...

  3. DZ升级到X3.2后,UCenter用户管理中心进不了了

    前天将DZ升级到X3.2后,UCenter用户管理中心进不了了,输入的密码也对,验证码也对,就是点登录后没反应,又回来输入前的状态.如果更换密码后,显示密码错误,证明密码是没错的.但就是进不了.大家看 ...

  4. 【prism】前期准备

    在网上下了prism框架源码,目前最新版本为4.1,其中包含的内容如下: 其中包含三类文件: 1.类似于Desktop only-Prism Library.bat的批处理文件,用来打开相应的Pris ...

  5. C Primer Plus(第五版)学习笔记-可变宏:...和__VA_ARGS__

    一 .__VA_ARGS__ P454 所讲printf()这些输出函数的参数是可变的,在调试程序时,可能希望定义参数为可变的输出函数, 那么可变参数宏会是一个选择,例如: #define DEBUG ...

  6. unity3d游戏开发(一)——圈圈叉叉

    参考:http://game.ceeger.com/forum/read.php?tid=1719 ———————————————————开始————————————— 好吧,吹了那么多我们开始吧,先 ...

  7. 仿今日头条最强顶部导航指示器,支持6种模式-b

    项目中经常会用到类似今日头条中顶部的导航指示器,我也经常用一个类似的库PagerSlidingTabStrip,但是有时并不能小伙伴们的所有需求,所以我在这个类的基础上就所有能用到的情况做了一个简单的 ...

  8. CSS 元素透明

    1.HTML 元素透明 其实本身,CSS 实现元素透明是件容易事儿.直接上代码: opacity:.5 opacity 指的是不透明度,取值为 0~1 之间,1 表示完全不透明,0 表示完全透明. A ...

  9. How to Run Node.js with Express on Mobile Devices

    We released a JXcore plugin for Apache Cordova recently and in this article I will show how to run a ...

  10. Yours 的博客开张啦!

    虽然申请博客已经1个月了,但是一直没有来写,没办法,题都刷不完,哪有心思写啊``` 现在集训终于完了,有了属于自己的时间了.所以该把以前做的题,学的算法好好的整理整理了.一来顺顺思路,二来也可以给后来 ...