Action Filters for ASP.NET MVC
本文主要介绍ASP.NET MVC中的Action Filters,并通过举例来呈现其实际应用。
Action Filters 可以作为一个应用,作用到controller action (或整个controller action中),以改变action的行为。
ASP.NET MVC Framework支持四种不同类型的Filter:
- Authorization filters – 实现
IAuthorizationFilter接口的属性
. - Action filters – 实现
IActionFilter接口的属性
. - Result filters – 实现
IResultFilter接口的属性
. - Exception filters – 实现
IExceptionFilter接口的
属性。
Filter 的默认执行顺序,如上面的编号顺序。验证(authorization)filter永远都是最开始执行的,异常(exception)filter永远都是最后执行的。
下面只详细介绍Action Filters。
在Action Filters中 ASP.NET MVC Framework 提供了ActionFilterAttribute父类。
所以在Action,Result执行之前之后分别做一些操作,就需要重写ActionFilterAttribute父类,并实现父类中的虚方法。
下面,我们假设一种场景。当我们打开管理系统的页面时,需要进行权限检查,假如多个页面都需要权限检查,重复的代码,必然会让我们感到抓狂。
这时候就可以利用ActionFilterAttribute父类重写OnActionExecuting()方法进行权限检查。
首先,我们在App_Start中添加一个新类,继承ActionFilterAttribute父类。代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcMobileDMS.App_Start { //[AttributeUsage(AttributeTargets.All, AllowMultiple = true)] public class ActionAttributeFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { //在Action执行前执行 if (filterContext.HttpContext.Session["temp"] == null) { filterContext.HttpContext.Response.Redirect("~/dms/logon"); } //filterContext.HttpContext.Response.Redirect("dms/add"); base.OnActionExecuting(filterContext); } } }
我们假设当系统中存在Session["temp"],则验证通过。否则跳到登陆页面。
好了,ActionFilterAttribute父类已经重写,那么如何运用到我们的Action中呢?很简单,看代码:
[MvcMobileDMS.App_Start.ActionAttributeFilter()] public ActionResult Add() { Session.Remove("temp"); return View(); }
在Action 方法上添加[MvcMobileDMS.App_Start.ActionAttributeFilter()]即可。即我们新增的类。这样每次访问add页面就要做权限检查。
那么,我们再想深一层,假如我想所有的页面都执行权限检查呢?看代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcMobileDMS.Controllers { [MvcMobileDMS.App_Start.ActionAttributeFilter()] public class DMSController : Controller { // // GET: /DMS/ //[MvcMobileDMS.App_Start.ActionAttributeFilter()] public ActionResult Index() { //AVON.DMS.DAL.Entities DMS = new AVON.DMS.DAL.Entities(); //AVON.DMS.Model.REP A = DMS.REP.SingleOrDefault<AVON.DMS.Model.REP>(t => t.NO == "00561874"); //AVON.DMS.BLL.Rep repBLL = new AVON.DMS.BLL.Rep(); //AVON.DMS.Model.REP A = repBLL.GetFromRep("00561874"); //ViewData["mydata"] = A.JOINDATE; ViewData["mydata"] = "index"; return View(); } //[MvcMobileDMS.App_Start.ActionAttributeFilter()] public ActionResult Add() { Session.Remove("temp"); return View(); } public ActionResult logon() { Session["temp"] = "aaa"; return View(); } public string test() { return "hahah"; } } }
在DMSController类前,我添加了[MvcMobileDMS.App_Start.ActionAttributeFilter()],如此,所有的action在运行前都会执行OnActionExecuting方法,即权限检查。
如果,我们再更想深一层,我们想所有的Controller都执行呢?也很简单,只需修改Global.asax代码,如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace MvcMobileDMS { // Note: For instructions on enabling IIS6 or IIS7 classic mode, // visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalFilters.Filters.Add(new MvcMobileDMS.App_Start.ActionAttributeFilter()); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } } }
只要添加全局GlobalFilter即可。GlobalFilters.Filters.Add(new MvcMobileDMS.App_Start.ActionAttributeFilter());
希望对你有所帮助O(∩_∩)O哈哈~。