为了让用户更简单的创建一个自定义Action filter,ASP.NET MVC Framework提供了一个基类ActionFilterAttribute,这个类实现了IActionFilter和IResultFilter接口,并且继承了FilterAttribute类。从广义上来说,在ASP.NET MVC Framework中,任何实现filter的类型都是action filter。
ActionFilter成员:
- OnActionExecuting – 在controller action执行之前调用
- OnActionExecuted – 在controller action执行之后调用
- OnResultExecuting – 在controller action result执行之前调用
- OnResultExecuted – 在controller action result执行之后调用
执行顺序如下图:
下面是个小例子:
新建一个类MyActionFilter继承ActionFilterAttribute
public class MyActionFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { //记录时间 filterContext.HttpContext.Items["StartTime"] = DateTime.Now; //验证是否登录 var service = (IFormsAuthorizeService)filterContext.Controller; //子控件不做权限验证 if (filterContext.IsChildAction) return; //源请求页面url地址 string url = filterContext.HttpContext.Request.RawUrl; if (!service.SignIn()) { if (filterContext.HttpContext.Request.IsAjaxRequest()) { JsonResult jr = new JsonResult(); jr.Data = new { url = "/passport/login" }; jr.JsonRequestBehavior = JsonRequestBehavior.AllowGet; filterContext.Result = jr; } else filterContext.Result = new RedirectResult("/passport/login?redirectUrl=" + url); } } public override void OnActionExecuted(ActionExecutedContext filterContext) { //处理异常 if (filterContext.Exception != null) { filterContext.ExceptionHandled = true; filterContext.Result = new RedirectToRouteResult("Default" , new System.Web.Routing.RouteValueDictionary(new { action = "OnError" })); } } public override void OnResultExecuting(ResultExecutingContext filterContext) { //压缩输出结果 string acceptEncoding = filterContext.HttpContext.Request.Headers["Accept-Encoding"]; if (string.IsNullOrEmpty(acceptEncoding)) return; var response = filterContext.HttpContext.Response; acceptEncoding = acceptEncoding.ToUpperInvariant(); if (acceptEncoding.Contains("GZIP")) { response.AppendHeader("Content-encoding", "gzip"); response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); } else if (acceptEncoding.Contains("DEFLATE")) { response.AppendHeader("Content-encoding", "deflate"); response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); } } public override void OnResultExecuted(ResultExecutedContext filterContext) { //计算出页面相应时间 DateTime statTime = (DateTime)filterContext.HttpContext.Items["StartTime"]; TimeSpan diff = DateTime.Now - statTime; filterContext.HttpContext.Response.Write("<hr />" + diff.ToString()); } }