面向切面编程:Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题。AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。比如我们最常见的就是日志记录了
面向切面编程也就是使用过滤器,过滤器就是当出现某种情况,执行一段额外的代码,比如异常过滤器,代码中任何一个地方出现异常都会执行
过滤器 必须以Attribute结尾,想控制器一Controller结尾一个道理
自定义过滤器
若要自定义一个过滤器,则要继承ActionFilterAttribute类,这个类是一个抽象类,实现了IActionFilter和IResultFilter接口,主要通过重写四个虚方法来达到在行为方法执行和返回的前后注入逻辑
方法 | 参数 | 描述 |
OnActionExecuting | ActionExecutingContext | 在行为方法执行前执行 |
OnActionExecuted | ActionExecutedContext | 在行为方法执行后执行 |
OnResultExecuting | ResultExecutingContext | 在行为方法返回前执行 |
OnResultExecuted | ResultExecutedContext | 在行为方法返回后执行 |
四个方法执行顺序是OnActionExecuting——>OnActionExecuted——>OnResultExecuting——>OnResultExecuted。上面四个方法的参数都是继承基ContollorContext类。例如下面定义了一个自定义的过滤器
过滤器代码:
namespace MvcValidateDemo.Models { //AllowMultiple = true:允许多个标签同时都起作用 //[AttributeUsage(AttributeTargets.All,AllowMultiple = true)] public class MyActionFilterAttribute : ActionFilterAttribute { public string Name { get; set; } //Action 执行之前先执行此方法 public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); HttpContext.Current.Response.Write("<br />OnActionExecuting :" + Name); } //Action执行之后 public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); HttpContext.Current.Response.Write("<br />OnActionExecuted :" + Name); } //ActionResult执行之前先执行此方法 public override void OnResultExecuting(ResultExecutingContext filterContext) { base.OnResultExecuting(filterContext); HttpContext.Current.Response.Write("<br />OnResultExecuting :" + Name); } public override void OnResultExecuted(ResultExecutedContext filterContext) { base.OnResultExecuted(filterContext); HttpContext.Current.Response.Write("<br />OnResultExecuted :" + Name); } } }
使用该过滤器即在action/类上添加该类的标记:
namespace MvcValidateDemo.Controllers { [MyActionFilter(Name = "HomeController")] public class HomeController : Controller { // // GET: /Home/ [MyActionFilter(Name = "Index Action")] public ActionResult Index() { Response.Write("<p>Action执行了</p>"); return Content("<br />ok:视图被渲染<br />"); } public ActionResult About() { return Content("<P>About 渲染</P>"); } } }
如果想定义全局过滤器,比如登录验证,不通过的跳转的登陆页
App_Start文件夹内的FilterConfig.cs文件就是放所有的全局过滤器
namespace MvcValidateDemo { public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new MyExceptionFilterAttribute()); //全局过滤器,优先级最低,但是可以作用到所有的控制器和action //filters.Add(new MyActionFilterAttribute(){Name = "Gloable"}); } } }
如果想让 控制器、Action、全区过滤器上的过滤器全部起作用,在过滤器类上加上下面这句话
//AllowMultiple = true:允许多个标签同时都起作用 [AttributeUsage(AttributeTargets.All,AllowMultiple = true)] public class MyActionFilterAttribute : ActionFilterAttribute {
//页面跳转到错误页面或者是首页 HttpContext.Current.Response.Redirect("/Home/Index");