.NET MVC 过滤器使用
来看以下两种情况
1. 如果我们需要对某个模块做权限控制,通常的做法是写一个基类(BaseController),让这个基类继承Controller类,在BaseController的构造方法中进行权限校验的操作,然后让需要进行校验的类继承 BaseController
2. 如果我们需要自定义错误异常处理,固然我们可以对可能出错的地方都写上 try catch ,但是这几乎不可能实现,因为很多错误我们自己也无法预知
在.net MVC中给我们提供了一种解决方案,那就是过滤器
.net framework给我们提供了四种不同类型过滤器
过滤器类型 | 实现接口 | 默认实现 | 重写方法 | 描述 |
Authorization | IAuthorizationFilter | AuthorizeAttribute | OnAuthorization | 在方法和所有过滤器前执行 |
Action | IActionFilter | ActionFilterAttribute |
OnActionExecuting OnActionExecuted |
方法执行之前和之后 |
Result | IResultFilter | ActionFilterAttribute |
OnResultExecuted OnResultExecuting |
结果执行之前和之后 |
Exception | IExceptionFilter | HandleErrorAttribute | OnException | 抛出异常时执行 |
过滤器两种定义方式:
1. 单独建立一个过滤器类,然后在需要使用该过滤器的方法或者类前面使用特征的方式加上该过滤器,或者使用全局注册的方式 (推荐)
权限校验:
public class MyAuthorization:AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { //RouteData 获取路由数据 List<KeyValuePair<string, object>> router_data = filterContext.RouteData.Values.ToList(); //在这里进行权限判断,如果具备权限,则跳转到错误页面 filterContext.HttpContext.Response.Write("检查权限"); //跳转到 Auth 控制器下 Login 方法 filterContext.Result = new RedirectResult("Auth/Login"); //这种跳转方法不会终止程序执行 //filterContext.HttpContext.Response.Redirect("Auth/Login") //注释掉此行代码,否则将执行系统定义的过滤器 //base.OnAuthorization(filterContext); }
//在需要进行权限校验的方法或者类前面加上该过滤器 [MyAuthorization] public ActionResult Index() { return View(); }
异常处理:
public override void OnException(ExceptionContext filterContext) { //日志记录,然后跳转到错误页 filterContext.Result = new RedirectResult("/error/400.html"); //这行代码不可以被删除 否则捕捉不到异常 base.OnException(filterContext); }
然后在 App_Start/FilterConfig.cs 中全局注册
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { //注释掉系统注册的全局异常处理 //filters.Add(new HandleErrorAttribute()); filters.Add(new MyException()); }
最后需要在根目录 web.config中开启自定义异常处理
//在 system.web 节点中添加 <customErrors mode="On"> </customErrors>
2. 在控制器中重写对应方法,然后改控制器下所有方法都会自动使用该控制器
protected override void OnAuthorization(AuthorizationContext filterContext) { filterContext.HttpContext.Response.Write("这是控制器中重写的方法"); }