Filter拦截器
Aop是MVC的主要设计方式之一,而微软也希望我们在使用MVC的时候更好的使用拦截器来进行切面编程。拦截器则是Mvc中的一大亮点与重点
AOP(面向切面)编程已经广泛应用在各个项目中,切面编程把我们的action切出了执行前与执行后或者是特定的需求比如异常发生时。让我们可以在切面中从容的完成记日志、检查权限等操作。在action中开发人员只需要关于核心业务。
可以看到Controller已经为我们集成了一些Filter接口
IActionFilter -- > Action执行前后
IAuthenticationFilter --> Action安全验证
IAuthorizationFilter --> Action身份验证
IExceptionFilter --> Action出现异常时
IResultFilter --> 结果返回前后
但是我们的Controller并没有去实现这些接口中的方法,而是留给了子类也就是xxxController我们的控制器去实现。我们可以去重写方法,但是这种方式只能在当前的控制器生效,并不能在其它的控制器中生效,这显然并不是我们想要的。
现在我需要在action执行前去验证一下参数的合法性并适用与所有的Controller,我们可以创建一个Attribute继承IActionFilter和Attribute,更简单的我们可以直接继承ActionFilterAttribute重写OnActionExecuting方法 (actionFilterAttribut继承了IActionFilter与IResultFilter)
下面进行了简单的一个判断,如果UserName为null或者不等于admin就跳转到Error页面
然后再加到action上就可以完成了,但是上面提到了,我们在所有的Controller中都要用到,难道里面每个action都要去加,这太麻烦。 我们可以加到Filter的集合中在Global中进行初化。
浅谈内部原理
这里不对所有的拦截器都演示一次,因为讲起来篇幅挺多的。大多在博客园都可以找到不错的文章。这里讲一下像ActionFilter背后是如何实现的,是如何在action前后进行拦截的
重点其实就在AsyncControllerActionInvoker类中的InvokeActionMethodFilterAsynchronouslyRecursive方法,在这里执行了filter的OnActionExceuting方法,然后判断Result是否为空,否的话就直接到OnActionExecuted不会走action了。 在try里可以看到方法是递归调用的,正常的话会去执行我们的action然后再回到这边调用OnActionExceuted