一直都知道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