跟我一块儿学.NetCore之MVC过滤器,这篇看完走路能够仰着头走

前言前端

MVC过滤器在以前Asp.Net的时候就已经普遍使用啦,不论是面试仍是工做,总有一个考点或是需求涉及到,能够绝不疑问的说,这个技术点是很是重要的; 在以前参与的面试中,得知不少小伙伴只知道有一两个过滤器,而对其执行顺序了解的仍是很模糊,少部分小伙伴甚至尚未使用过。这里就详细来讲说这块的内容。面试

正文后端

来,直接上菜,而后再慢慢品;在Asp.NetCore 中,MVC有如下五种过滤器,根据执行顺序的不一样,用于不一样场景:
设计模式

上图中大概的流程以下:
缓存

  1. 用户发起一个请求;
    服务器

  2. 请求通过Asp.NetCore应用程序的中间件管道;测试

  3. 管道走完以后进入MVC的第一个过滤器:受权过滤器;设计

  4. 受权经过以后进入资源过滤器的前置方法;
    日志

  5. 将异常过滤器加入使用,后续有异常能够进行捕获,以前若是发生异常不能捕获;
    中间件

  6. 进行数据模型绑定,好比参数经过数据模型绑定传参;

  7. 进入Action过滤器前置方法;

  8. 执行Action方法具体逻辑;

  9. 进入Action过滤器后置方法;

  10. 进入Result过滤器前置方法;

  11. 渲染Result结果;

  12. 进入Result过滤器后置方法;

  13. 进入资源过滤器的后置方法;

  14. 进入中间件管道返回;

  15. 最后将响应结果展示给用户;

接下来就好好说说每种过滤器的使用,老规矩,仍是WebApi项目↓↓↓

  1. 受权过滤器(Authorization Filter)

    受权,用于验证请求是否有权限访问对应的Action,通常包含登陆验证、菜单权限(即接口权限)验证等。受权过滤器只对请求进行验证,是单向的,响应返回时不走该过滤器;

    代码撸起来:

    这里先进行全局注册过滤器进行测试,即只要注册以后,全部请求都须要通过受权过滤器校验,后续单独说说注册方式范围:

    在默认生成的接口中打印字符串,方便看执行结果:

    运行看结果:

    经过上图能够看到,已经进入受权过滤器中进行相关逻辑判断;若是将受权逻辑中的局部变量validate设置为true,运行结果以下:

    看过上一篇(跟我一块儿学.NetCore之熟悉的接口权限验证不能少(Jwt))的小伙伴确定有疑问:这和受权中间件中使用Authorize特性受权有什么区别?没看过的小伙伴也不要紧,应该也会有一样的疑问;来,听我慢慢道来,老套路,扒扒受权中间件的代码,看看怎么回事?


    先来看看Authorize特性里面都有什么,关键是实现了IAuthorizeData接口,以下图:

    找到受权的入口点,即中间件注册受权那里着手,以下图:

    从而找AuthorizationMiddleware的具体实现,关键代码以下图:

    总的来讲,使用受权中间的时,标注Authorize特性的Action,会经过默认的AuthorizeFilter进行验证处理,这就是为何在上一节权限验证的时候咱们没有单独编写受权过滤器,而是偏重于校验的逻辑,只关注验证的角色或策略;这里就不打算再看AuthorizeFilter的源码,有兴趣的小伙伴好好研究研究。

  2. 资源过滤器(Resource Filter)

    资源过滤器分为前置方法和后置方法,通常都会在前置方法作相关处理,好比说须要改改模型绑定的逻辑,但更多经常使用的是用于数据缓存处理,由于是在受权过滤器以后的第一个,若是取得缓存数据,直接返回结果,就减小后面代码逻辑执行;后置方法在以后全部代码逻辑执行完成,返回时通过。

    代码撸起来:

    这里仍是以全局的方式进行注册资源过滤器:

    运行效果以下:

    将受权过滤器中的validate改成false,这里模拟表明有权限继续执行:

  3. 异常过滤器(Exception Filter)

    用于服务器向客户端写入响应内容以前进行系统异常捕获,通常用于业务场景统一异常的处理,若是没有特殊需求,没必要每种业务都进行异常处理,经过异常过滤器统一捕获处理便可,记录相关日志,便于异常问题分析;

    先模拟处理业务时,抛异常了,以下:

    异常信息直接返回给用户,体验是至关很差的,因此通常会将异常进行捕获处理,因为异常信息容易让开发者进行问题排查,因此通常会将其以日志的形式记录;系统中确定会考虑不少异常的地方,不可能到处都进行手动捕获一下再处理,显得代码臃肿的同时还很差维护,因此用异常过滤器统一进行捕获处理就显得颇有必要了,固然,一些很关键的业务能够进行单独捕获处理;异常过滤使用以下:

    将其全局注册,看运行效果:

    小伙伴看到这,有没好奇为何不在受权过滤器和资源过滤器中抛出异常测试,而是选择在Action方法中抛出异常,还记得第一张图过滤器顺序吗(小伙伴再去重温一下~),那是由于受权过滤器和资源过滤器那尚未异常过滤器,因此发生异常时捕获不到,这也是小伙伴要特别注意的,须要本身处理好异常;只要在异常过滤器以后请求处理的异常都能捕获到啦;


  4. Action过滤器(Action Filter)

    Action过滤器有前置和后置两种方法,通常偏向于业务使用,好比在前置方法中进行验证模型绑定参数的合法性,也能够对参数进行加工等;后置方法能够对返回结果的处理;

    平时用的比较多,以下:

    全局注册,运行以下:

    有没有想试一下,在Action过滤器方法中抛出异常时,看看异常过滤器能不能捕获到,答案确定是:能,但在这不截图给小伙伴们看,小伙伴们动手试试嘛。

  5. Result过滤器(Result Filter)

    Result过滤器也有前置和后置两种方法,前置方法能够在结果没返回前,能够对Action返回的结果进行干预处理,后置方法通常是结果已经渲染以后执行;

    API项目用的很少,在MVC Web项目比较适用,使用方式以下:

    将其进行全局注册,运行以下:

    一样在此过滤器中抛出异常,异常过滤器捕获不到啦。

    意不意外,惊不惊喜,其实只要开始进行响应结果处理时,异常过滤器就不捕获对应异常,须要本身单独处理;

过滤器的注册范围

除了上面的全局注册,过滤器还能够以特性的方式标注在控制器或对应Action方法上:

全局注册:针对系统中全部过滤器都有效;

标注在控制器上(Controller):对标注控制器中全部Action方法都有效;

标注在Action上:只针对对应的Action有效;

思路:若是有极个别Action不想使用统一的过滤器,能够经过标注特性的方式在对应过滤器逻辑中将其进行过滤掉。

过滤器注册方式

  • 全局方式注册

    在Startup中ConfigureServices注册服务时全局注册过滤器,以下图:

  • 特性方式标注

    A、继承Attribute类时,能够直接标注在控制器(Controller)和Action上,以下图:

    B、没有继承Attribute类的状况,借用TypeFilter、ServiceFilter或自定义IFilterFactory进行特性标注。

    TypeFilter的方式,以下图:

    ServiceFilter的方式须要单独注册一下过滤器服务,控制生命周期,若是没有注册过滤器服务会报异常,以下图:

    注册过滤器服务就正常了,以下图:

    自定义IFilterFactory,先实现一个特性类,以下:

    使用以下:

同种过滤器的执行顺序

对于不一样类型过滤器的执行顺序,开篇的图就说明了,接下来讲多个同种过滤器的执行顺序;

  • 不一样范围的同种过滤器顺序

    上面说到过滤的注册范围,有全局注册、控制器标注、Action标注,同种过滤器在不一样范围注册是什么个顺序?这里以经常使用的Action过滤器为例,其余过滤器的练习就交给小伙伴了,这里复制出MyActionFilter两份,分别更名为MyActionFilter1和MyActionFilter2,其中MyActionFilter用于全局注册,MyActionFilter1用于控制器特性标注,MyActionFilter2用于Action方法标注,运行结果以下:

    结论:全局注册->控制器->Action。

  • 相同范围的同种过滤器顺序

    将MyActionFilter、MyActionFilter1和MyActionFilter2三个过滤器都标注在Action上,全局和控制器上都注释掉,看效果:

    结论:默认状况注册或特性标注顺序与执行顺序一致。

到这可能小伙伴会想:终于结束啦!!!,哈哈哈,nonono,对于过滤器的执行顺序,除了以上默认顺序以外,是能够任意调整的,经过实现IOrderedFilter接口,设置对应过滤器的顺序属性便可改变对应的顺序,Order值越小,优先级就越高,以下使用:

没有效果图,差评? 别别别,这里是督促小伙伴本身试一把,否则小伙伴看一下就完事了(不本身操做一把,过两天就会忘),有没有用心良苦~

重点:Order排序优先于范围排序,即先会以Order进行排序,若是一致,再以注册的范围排序。

总结

好啦,完啦!主要分享了MVC各类过滤器的使用,大概的应用场景,执行顺序,注册范围及注册方式。有没有感受脖子有点小酸,来,起来走走,仰着头的那种,标题是否是没骗小伙伴,绝对真实。 下一篇说说MediatR组件和中介者设计模式。

整理了一些面试资料,关注公众号“Code综艺圈”,发送"面试"获取下载地址,至于教程,手里的也有一些Web前端、.Net后端、Java的教程,但如今网上资源比较多,大部分小伙伴喜欢在线看;若是有须要,小伙伴能够私聊我,目前先把面试相关的资料放上去,收集内容会持续更新,包含一些大厂面试题,助力小伙伴找到心仪的工做:

教程截取部分图以下,有须要私聊我:

一个被程序搞丑的帅小伙,关注"Code综艺圈",识别关注跟我一块儿学~~~

撸文不易,莫要白瞟,三连走起~~~~

相关文章
相关标签/搜索