ASP.NET MVC中的ActionFilter介绍学习

一直都知道MVC中的ActionFilter,只是没有在实际项目中使用过。

顾名思义,ActionFilter就是指在Action上的Filter, 那么,在Action上的Filter到底有哪些呢。首先我们看看MVC中的Controller基类(抽象类)

  public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer
    {
    }

我们可以看到,它有5个Filter,分别是IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IExceptionFilter, IResultFilter. 我们先看看第一个IActionFilter

IActionFilter解析

从名称就可以看出,IActionFilter是一个接口.源码如下
    //
    // 摘要:
    //     Defines the methods that are used in an action filter.
    public interface IActionFilter
    {
        //
        // 摘要:
        //     Called after the action method executes.
        //
        // 参数:
        //   filterContext:
        //     The filter context.
        void OnActionExecuted(ActionExecutedContext filterContext);
        //
        // 摘要:
        //     Called before an action method executes.
        //
        // 参数:
        //   filterContext:
        //     The filter context.
        void OnActionExecuting(ActionExecutingContext filterContext);
    }

可以看到,该接口中有两个方法,一个是OnActionExecuted (执行完Action之后执行该方法),另一个是OnActionExecuting(执行Action之前执行该方法)

也就是这两个方法分别在Action的前后执行. 所以它可以用于记录日志,获取action的访问量......

知道了之后,那么我们如何来实现ActionFilter呢。 

我们注意到,Controller基类继承了IActionFilter接口,而我们在MVC中写的Controller又都继承自Controller基类, 所以我们应该可以直接在MVC的Controller中override这两个方法

1. 用override的方式来实现ActionFilter

 1     public class HomeController : Controller
 2     {
 3         public ActionResult Index()
 4         {
 5             return View();
 6         }
 7 
 8         protected override void OnActionExecuting(ActionExecutingContext filterContext)
 9         {
10             filterContext.HttpContext.Response.Write("Execute something before action");
11 
12             base.OnActionExecuting(filterContext);
13         }
14 
15         protected override void OnActionExecuted(ActionExecutedContext filterContext)
16         {
17             filterContext.HttpContext.Response.Write("Execute something after action");
18 
19             base.OnActionExecuted(filterContext);
20         }
21     }

这样好像就可以的,但是它有个问题,就是它只能用于HomeController, 有没有一种方法,我能写一个ActionFilter,可以用于多个Controller中的不同Action呢

显然,可以做到。我们可以自己写一个ActionFilter的类,使它继承IActionFilter, 如下:

2. 自定义一个ActionFilter 属性来实现IActionFilter接口

 1    public class MyActionFilterAttribute : Attribute, IActionFilter
 2     {
 3         public void OnActionExecuted(ActionExecutedContext filterContext)
 4         {
 5             filterContext.HttpContext.Response.Write("Execute something before action");
 6         }
 7 
 8         public void OnActionExecuting(ActionExecutingContext filterContext)
 9         {
10             filterContext.HttpContext.Response.Write("Execute something after action");
11         }
12     }

 好了,到现在我们就有自己写的ActionFilter了,叫做“MyActionFilter”, 如何使用它呢,很简单的

1     public class HomeController : Controller
2     {
3         [MyActionFilter]
4         public ActionResult Index()
5         {
6             return View();
7         }
8     }

除了上面两种方法,还有没有其他方法呢。事实上是有的,MVC Framework自己给我们提供了一个ActionFilterAttribute特性,这也是一个抽象类,我们来看看源码

 1     //
 2     // 摘要:
 3     //     Represents the base class for filter attributes.
 4     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
 5     public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
 6     {
 7         //
 8         // 摘要:
 9         //     Initializes a new instance of the System.Web.Mvc.ActionFilterAttribute class.
10         protected ActionFilterAttribute();
11 
12         //
13         // 摘要:
14         //     Called by the ASP.NET MVC framework after the action method executes.
15         //
16         // 参数:
17         //   filterContext:
18         //     The filter context.
19         public virtual void OnActionExecuted(ActionExecutedContext filterContext);
20         //
21         // 摘要:
22         //     Called by the ASP.NET MVC framework before the action method executes.
23         //
24         // 参数:
25         //   filterContext:
26         //     The filter context.
27         public virtual void OnActionExecuting(ActionExecutingContext filterContext);
28         //
29         // 摘要:
30         //     Called by the ASP.NET MVC framework after the action result executes.
31         //
32         // 参数:
33         //   filterContext:
34         //     The filter context.
35         public virtual void OnResultExecuted(ResultExecutedContext filterContext);
36         //
37         // 摘要:
38         //     Called by the ASP.NET MVC framework before the action result executes.
39         //
40         // 参数:
41         //   filterContext:
42         //     The filter context.
43         public virtual void OnResultExecuting(ResultExecutingContext filterContext);
44     }

所以,我们可以写一个自己的ActionFilter属性,来实现MVC Framework提供的这个类ActionFilterAttribute就好

3. 自定义一个ActionFilter 类来继承ActionFilterAttribute类
namespace MyApplication.Controllers
{
    public class HomeController : Controller
    {
       [MyActionFilter]
       public ActionResult Index()
        {
            return View();
        }
    }

    public class MyActionFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);
        }
    }
}
以上参考 http://www.cnblogs.com/huangxincheng/p/5671106.html
原文地址:https://www.cnblogs.com/wphl-27/p/9322792.html