原文链接 https://blog.csdn.net/pan_junbiao/article/details/84523935
比如 ActionFilter中ActionExecutingContext filterContext可以拿到请求中的上下文。可以拿到请求action的名字controller的名字。和要请求的action 的上的标签等。filterContext.Result 可以给响应复制。截断请求,从而执行当前返回结果。
MVC Filter是典型的AOP(面向切面编程)应用,在ASP.NET MVC中的4个过滤器类型,如下:
| 过滤器类型 | 接口 | 默认实现 | 描述 | 
|---|---|---|---|
| Action | IActionFilter | ActionFilterAttribute | 在动作方法之前及之后运行 | 
| Result | IResultFilter | ActionFilterAttribute | 在动作结果被执行之前和之后运行 | 
| AuthorizationFilter | IAuthorizationFilter | AuthorizeAttribute | 首先运行,在任何其它过滤器或动作方法之前 | 
| Exception | IExceptionFilter | HandleErrorAttribute | 只在另一个过滤器、动作方法、动作结果弹出异常时运行 | 
但是默认实现它们的过滤器只有三种,分别是ActionFilter(方法),Authorize(授权),HandleError(错误处理)。
1、Action过滤器
在ASP.NET MVC中创建MvcApp项目,创建文件夹Filter,然后新建类MyActionFilterAttribute(为了遵循默认的约定,名称以Attribute结尾),继承自ActionFilterAttribute类。ActionFilterAttribute类有如下4个方法。
- using System;
-  
- namespace System.Web.Mvc
- {
-     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
-     public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
-     {
-  
-         protected ActionFilterAttribute();
-  
-         public virtual void OnActionExecuted(ActionExecutedContext filterContext);
-  
-         public virtual void OnActionExecuting(ActionExecutingContext filterContext);
-  
-         public virtual void OnResultExecuted(ResultExecutedContext filterContext);
-  
-         public virtual void OnResultExecuting(ResultExecutingContext filterContext);
-     }
- }
实现MyActionFilterAttribute类:
- using System;
- using System.Web.Mvc;
-  
- namespace MvcApp.Filter
- {
-     public class MyActionFilterAttribute : ActionFilterAttribute
-     {
-         public override void OnActionExecuting(ActionExecutingContext filterContext)
-         {
-             //1、获取请求的类名和方法名
-             string strController = filterContext.RouteData.Values["controller"].ToString();
-             string strAction = filterContext.RouteData.Values["action"].ToString();
-  
-             //2、用另一种方式获取请求的类名和方法名
-             string strController2 = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
-             string strAction2 = filterContext.ActionDescriptor.ActionName;
-  
-             filterContext.HttpContext.Response.Write("控制器:" + strController + "<br/>");
-             filterContext.HttpContext.Response.Write("控制器:" + strController2 + "<br/>");
-             filterContext.HttpContext.Response.Write("Action:" + strAction + "<br/>");
-             filterContext.HttpContext.Response.Write("Action:" + strAction2 + "<br/>");
-  
-             filterContext.HttpContext.Response.Write("Action执行前:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");
-             base.OnActionExecuting(filterContext);
-         }
-  
-         public override void OnActionExecuted(ActionExecutedContext filterContext)
-         {
-             filterContext.HttpContext.Response.Write("Action执行后:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");
-             base.OnActionExecuted(filterContext);
-         }
-     }
- }
对于过滤器,我们可以把它们加在3个地方,一个是控制器上面(控制器下面的所有Action),一个是Action上面(指定标识的Action),另一个就是全局位置(所有控制器中的Action)。这里只演示在Action上面和Home控制器中:
- [MyActionFilter]
- public ActionResult Index()
- {
-     return View();
- }
2、Result过滤器
新建MyResultFilterAttribute类,继承ActionFilterAttribute:
- using System;
- using System.Web.Mvc;
-  
- namespace MvcApp.Filter
- {
-     public class MyResultFilterAttribute : ActionFilterAttribute
-     {
-         /// <summary>
-         /// 加载“视图”前执行
-         /// </summary>
-         /// <param name="filterContext"></param>
-         public override void OnResultExecuting(ResultExecutingContext filterContext)
-         {
-             filterContext.HttpContext.Response.Write("加载视图前执行 OnResultExecuting" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");
-             base.OnResultExecuting(filterContext);
-         }
-  
-         /// <summary>
-         /// 加载“视图”后执行
-         /// </summary>
-         /// <param name="filterContext"></param>
-         public override void OnResultExecuted(ResultExecutedContext filterContext)
-         {
-             filterContext.HttpContext.Response.Write("加载视图后执行 OnResultExecuted" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");
-             base.OnResultExecuted(filterContext);
-         }
-     }
- }
这里把MyResultFilter过滤器加在控制器上面,相当于给Home控制器中的所有的Action方法添加了MyResultFilter过滤器。
- using MvcApp.Filter;
- using System.Web.Mvc;
-  
- namespace MvcApp.Controllers
- {
-     [MyResultFilter]
-     public class HomeController : Controller
-     {
-         [MyActionFilter]
-         public ActionResult Index()
-         {
-             return View();
-         }
-  
-     }
- }
3、AuthorizeAttribute过滤器
创建MyAuthorizeAttribute类,继承AuthorizeAttribute类:
- using System.Web.Mvc;
-  
- namespace MvcApp.Filter
- {
-     /// <summary>
-     /// 授权过滤器
-     /// </summary>
-     public class MyAuthorizeAttribute : AuthorizeAttribute
-     {
-         public override void OnAuthorization(AuthorizationContext filterContext)
-         {
-             filterContext.HttpContext.Response.Write("OnAuthorization<br/>");
-  
-             //注释掉父类方法,因为父类里的OnAuthorization方法会调用ASP.NET的授权验证机制
-             //base.OnAuthorization(filterContext);
-         }
-  
-     }
- }
在控制器Home中的Index上添加MyAuthorize过滤器:
- [MyAuthorize]
- [MyActionFilter]
- public ActionResult Index()
- {
-     return View();
- }
通常Authorize过滤器也是在全局过滤器上面的,主要用来做登录验证或者权限验证,在App_Start目录下的FilterConfig类的RegisterGlobalFilters方法中添加:
- public class FilterConfig
- {
-     public static void RegisterGlobalFilters(GlobalFilterCollection filters)
-     {
-         //filters.Add(new HandleErrorAttribute());
-  
-         //添加全局授权过滤器
-         filters.Add(new MyAuthorizeAttribute());
-     }
- }
在全局中注册过滤器,则所有控制器的所有行为(Action)都会执行这个过滤器。
运行结果,如下图:

4、Exception过滤器
创建MyHandleErrorAttribute类,继承HandleErrorAttribute类:
- using System;
- using System.Web.Mvc;
-  
- namespace MvcApp.Filter
- {
-     /// <summary>
-     /// 异常处理过滤器
-     /// </summary>
-     public class MyHandleErrorAttribute : HandleErrorAttribute
-     {
-         public override void OnException(ExceptionContext filterContext)
-         { 
-             //1、获取异常对象
-             Exception ex = filterContext.Exception;
-             
-             //2、记录异常日志
-  
-             //3、重定向友好页面
-             filterContext.Result = new RedirectResult("~/error.html");
-  
-             //4、标记异常已经处理完毕
-             filterContext.ExceptionHandled = true;
-  
-             base.OnException(filterContext);
-         }
-     }
- }
在Action上面添加MyHandleError过滤器:
- [MyHandleError]
- public ActionResult GetErr()
- {
-     int a = 0;
-     int b = 1 / a;
-     return View();
- }
创建异常错误友好提示页面error.html。
- <body>
-     自定义错误页面
- </body>
运行会自动跳转到error.html页面。
如果页面没有跳转,就需要去Web.config配置文件中的<system.web>节点下面添加如下配置节点,开启自定义错误:
<customErrors mode="On"></customErrors>通常这样的异常处理是放在全局过滤器上面的,只要任意Action方法报错就会执行MyHandleError过滤器中的代码。
修改App_Start目录下面的FilterConfig类:
- public class FilterConfig
- {
-     public static void RegisterGlobalFilters(GlobalFilterCollection filters)
-     {
-         //filters.Add(new HandleErrorAttribute());
-  
-         //添加全局授权过滤器
-         filters.Add(new MyAuthorizeAttribute());
-  
-         //添加全局异常处理过滤器
-         filters.Add(new MyHandleErrorAttribute());
-     }
- }
Global.asax下的代码:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Optimization;
- using System.Web.Routing;
-  
- namespace MvcApp
- {
-     public class MvcApplication : System.Web.HttpApplication
-     {
-         protected void Application_Start()
-         {
-             AreaRegistration.RegisterAllAreas();
-             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
-             RouteConfig.RegisterRoutes(RouteTable.Routes);
-             BundleConfig.RegisterBundles(BundleTable.Bundles);
-         }
-     }
- }
 
                     
                    
                 
                    
                 

 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号