前几天面试遇到这个问题,发现不是很了解,学习了下,这里记录下来
经常需要将用户的操作记录到日志中,或者是验证用户是否登录了网站,
面对这样的需求,以前的操作是自定义一个统一的全局方法,然后做处理,
在每个需要的页面中添加想要的函数调用,这导致了多个页面中存在了大
量重复的代码,这样的方式不太符合软件工程的思想。为了解决这个问题,
mvc为我们提供了过滤器来完成对应的功能,通过过滤器,我们只需要将
相应的业务处理代码写一次,再在相应的功能处通过特性的方式来使用写
好的过滤器。
一句话,我们可以用过滤器来分离与业务逻辑无关却经常需要执行的代码,
既保证业务逻辑的正确性,也保证了代码的简洁直观
先看一段示例:
public class Log : FilterAttribute, IActionFilter { public void OnActionExecuted(ActionExecutedContext filterContext) { Console.WriteLine("log-after"); //throw new NotImplementedException(); } public void OnActionExecuting(ActionExecutingContext filterContext) { Console.WriteLine("log-before"); //throw new NotImplementedException(); } } public class Exc : FilterAttribute, IExceptionFilter { public void OnException(ExceptionContext filterContext) { Console.WriteLine("err"); filterContext.ExceptionHandled = true; //throw new NotImplementedException(); } } public class HomeController : Controller { // GET: Home [Log] [Exc] public ActionResult Index() { throw new Exception("error"); //return View(); } }
这里我们自定义了一个用来处理异常的类和一个日志记录的类,
然后通过特性的方式将其添加到控制器中需要的地方,这样的代码就变得十分简洁了
那我们可以使用哪些过滤器呢,这里一共有四种过滤器,解释如下
- ActionFilter(方法过滤器):接口名为[IActionFilter],在控制器方法调用前/后执行
- ResultFilter(结果过滤器):接口名为[IResultFilter],在控制器方法调用完,跳转至view页面前/后执行
- AuthorizationFilter(授权过滤器):接口名为[IauthorizationFilter],所有过滤器中最先执行的
- ExceptionFilter(异常处理过滤器):接口名为[IExceptionFilter],在控制器方法抛出异常时执行
根据这里的执行顺序,我们可以在不同的需求下自行实现对应的控制器,
需要注意的是,除了我们需要实现对应的过滤器接口外,同时还需要保证对应的过滤器是特性类,
这里我们可以通过继承FilterAttribute类来实现。
接口内部方法解释
IExceptionFilter:OnException,发生异常时调用
IResultFilter:OnResultExecuted,控制器方法执行完调用VIEW页面后执行
OnResultExecutint,控制器方法执行完调用VIEW页面前执行
IAuthorizationFilter:OnAuthorization,最先调用
IActionFilter:OnActionExecuted,控制器方法执行后执行
OnActionExecutint,控制器方法执行前执行
记录下来,留待后查
2017 11.30 21:29