接上篇 ASP.NET MVC学习笔记-----Filter(1)
Action Filter
Action Filter可以基于任何目的使用,它需要实现IActionFilter接口:
public interface IActionFilter { void OnActionExecuting(ActionExecutingContext filterContext); void OnActionExecuted(ActionExecutedContext filterContext); }
顾名思义,OnActionExecuting方法将在Action方法执行前调用,而OnActionExecuted方法将在Action方法执行后调用。
我们可以看到,OnActionExecuting方法的参数filterContext的类型为ActionExecutingContext,它同样继承于ControllerContext,并额外提供了Result属性和ActionDesciptor属性,它们的作用在上篇已经介绍过。
同样,OnActionExecuted方法的参数filterContext的类型为ActionExecutedContext,继承于ControllerContext,额外提供了Result属性,ActionDescriptor属性和Exception属性(Action方法抛出的未处理异常).
多说无益,来看一个例子吧:
public class CustomerActionAttribute : FilterAttribute, IActionFilter { private Stopwatch timer; public void OnActionExecuting( ActionExecutingContext filterContext) { timer = Stopwatch .StartNew(); } public void OnActionExecuted( ActionExecutedContext filterContext) { timer.Stop(); if (filterContext.Exception == null ) { filterContext.HttpContext.Response.Write( string .Format("<div>Action执行时间:{0}</div>" , timer.Elapsed.TotalSeconds)); } } }
public class HomeController : Controller { [CustomerAction] public ViewResult Index() { return View(); } }
执行结果:
Result Filter
Result Filter跟Action Filter有些类似,但它是在ActionResult执行前后执行,Result Filter需要实现IResultFilter接口:
public interface IResultFilter { void OnResultExecuting(ResultExecutingContext filterContext); void OnResultExecuted(ResultExecutedContext filterContext); }
ActionFilterAttribute
ASP.NET MVC提供了ActionFilterAttribute,它是一个抽象类,继承FilterAttribute,实现IActionFilter和IResultFilter接口:
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter { public virtual void OnActionExecuting(ActionExecutingContext filterContext) { } public virtual void OnActionExecuted(ActionExecutedContext filterContext) { } public virtual void OnResultExecuting(ResultExecutingContext filterContext) { } public virtual void OnResultExecuted(ActionExecutingContext filterContext) { } }
感觉这个类,就是给我们提供方便的,让我们能根据需要重写相应的方法。
Global Filter
如果我们需要将一个Filter作用于所有的Controller和Action的话,我们可以在FilterConfig.cs中的RegisterGlobalFilters方法注册全局Filter:
public class FilterConfig { public static void RegisterGlobalFilters( GlobalFilterCollection filters) { filters.Add( new HandleErrorAttribute ()); filters.Add( new CustomerActionAttribute ()); } }
Filter 的执行顺序
总的来说(相同类型的Filter),Global Filter最先执行,随后执行的是作用于Controller的Filter,最后执行的是作用于Action的Filter。但是Exception Filter的执行顺序却是完全相反的。
如果是针对同一个Action或Controller的多个Filter(filer的类型相同),它们的执行顺序是未定的。但是我们可以通过指定Order属性来定义执行顺序。