ASP.NET Core 中的过滤器(Action过滤器,控制器过滤器,全局应用程序过滤器)

十年河东,十年河西,莫欺少年穷html

学无止境,精益求精编程

今儿是周六,苏州的天空飘着毛毛细雨,气温也降低了很多,上午去了苏州繁花中心,来到二楼,自学了会古筝,逛了逛商场,中午去了肯德基,给孩子买了鸡翅,我和我老婆大人各喝了一杯咖啡。下午回到家,躺在床上刷抖音,刷的时间长了,也就以为特别无聊,索性看看博客园吧,嘿嘿,因而我买了一瓶100ML的56度牛栏山二锅头,边吃花生米边看,本打算看netcore的中间件,因而百度搜了一些内容,大多数写的中间件都是参考微软教程,看的也是索然无味,有的说中间件相似于AOP,有的说中间件是HTTP请求管道中的一个组件,用于拦截你的http请求并决定是否把你的请求传递给下一个中间件,总的来讲,中间件就是一个横向切面编程,也就是所谓的AOP,这里我们不讨论中间件,咱们今天讨论的是和中间件功能相似的过滤器,何为过滤器呢?过滤器和中间件有何细微的差异呢?哈哈,其实本篇博客是转载的别人,原文地址:https://www.cnblogs.com/jlion/p/12394949.html缓存

首先感谢原文做者的贡献,其次我之因此转载这篇博客,一是由于做者写的好,二是由于这些知识和以前的MVC过滤器很相似,再者,我以前也写过过滤器的应用,好比MVC的登陆受权过滤器,对MVC的登陆受权过滤器有兴趣的小虎斑可参考个人博客:https://www.cnblogs.com/chenwolong/p/Attribute.html  和 https://www.cnblogs.com/chenwolong/p/Token.html 两篇博客。 安全

废话说多了,下面我们进入正题,以下:mvc

1、前言

在分享ASP.NET Core Filter 使用以前,先来谈谈AOP,什么是AOP 呢?函数

AOP全称Aspect Oriented Programming意为面向切面编程,也叫作面向方法编程,是经过预编译方式和运行期动态代理的方式实现不修改源代码的状况下给程序动态统一添加功能的技术。工具

AOP技术利用一种称为“横切”的技术,剖解开封装对象的内部,将影响多个类的公共行为封装到一个可重用的模块中,并将其命名为Aspect切面。所谓的切面,简单来讲就是与业务无关,却为业务模块所共同调用的逻辑,将其封装起来便于减小系统的重复代码,下降模块的耦合度,有利用将来的可操做性和可维护性。性能

利用AOP能够对业务逻辑各个部分进行隔离,从而使业务逻辑各部分之间的耦合度下降,提升程序的可重用性,同时提升开发效率。this

AOP的使用场景主要包括日志记录、性能统计、安全控制、事务处理、异常处理等。spa

2、Filter-过滤器

Filter是延续ASP.NET MVC的产物,一样保留了五种的Filter,分别是Authorization Filter、Resource Filter、Action Filter、Exception Filter及Result Filter。
经过不一样的Filter能够有效处理封包进出的加工,本篇将介绍ASP.NET Core的五种Filter运做方式。

2.1 Filter 介绍

ASP.NET Core 有如下五种Filter 可使用:

    • Authorization Filter:
      Authorization是五种Filter中优先级最高的,一般用于验证Request合不合法,不合法后面就直接跳过。
    • Resource Filter:Resource是第二优先,会在Authorization以后,Model Binding以前执行。一般会是须要对Model加工处理才用。
    • Exception Filter:异常处理的Filter。
    • Action Filter:最常使用的Filter,封包进出都会通过它,使用上没什么须要特别注意的。跟Resource Filter很相似,但并不会通过Model Binding。
    • Result Filter:当Action完成后,最终会通过的Filter。

3、五大Filter 的应用

这一篇章主要来说解Asp.Net Core 的五大过滤器的实现及用途.

3.1 Authonization Filter

权限控制过滤器
经过 Authonization Filter 能够实现复杂的权限角色认证登录受权等操做
实现事例代码以下:

public class AuthonizationFilter :Attribute,IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext context) { //这里能够作复杂的权限控制操做
            if (context.HttpContext.User.Identity.Name != "1") //简单的作一个示范
 { //未经过验证则跳转到无权限提示页
                RedirectToActionResult content = new RedirectToActionResult("NoAuth", "Exception", null); context.Result = content; } } }

3.2 Resource Filter

资源过滤器
能够经过Resource Filter 进行资源缓存防盗链等操做。
使用Resource Filter 要求实现IResourceFilter 抽象接口

public class ResourceFilter : Attribute,IResourceFilter { public void OnResourceExecuted(ResourceExecutedContext context) { // 执行完后的操做
 } public void OnResourceExecuting(ResourceExecutingContext context) { // 执行中的过滤器管道
 } }

3.3 Exception Filter

经过Execption Filter 过滤器能够进行全局的异常日志收集 等操做。

使用Execption Filter 要求实现IExceptionFilter 抽象接口
IExceptionFilter接口会要求实现OnException方法,当系统发生未捕获异常时就会触发这个方法。OnException方法有一个ExceptionContext异常上下文,其中包含了具体的异常信息,HttpContext及mvc路由信息。系统一旦出现未捕获异常后,比较常见的作法就是使用日志工具,将异常的详细信息记录下来,方便修正调试。下面是日志记录的实现。  

public class ExecptionFilter : Attribute, IExceptionFilter { private ILogger<ExecptionFilter> _logger; //构造注入日志组件
        public ExecptionFilter(ILogger<ExecptionFilter> logger) { _logger = logger; } public void OnException(ExceptionContext context) { //日志收集
            _logger.LogError(context.Exception, context?.Exception?.Message??"异常"); } }

3.4 Action Filter

做用:能够经过ActionFilter 拦截 每一个执行的方法进行一系列的操做,好比:执行操做日志参数验证权限控制 等一系列操做。

使用Action Filter 须要实现IActionFilter 抽象接口,IActionFilter 接口要求实现OnActionExecuted 和OnActionExecuting 方法

public class ActionFilter : Attribute, IActionFilter { public void OnActionExecuted(ActionExecutedContext context) { //执行完成....
 } public void OnActionExecuting(ActionExecutingContext context) { //执行中...
 } }

3.5 Result Filter

结果过滤器,能够对结果进行格式化、大小写转换等一系列操做。

使用Result Filter 须要实现IResultFilter 抽象接口,接口要求实现
OnResultExecuting 方法 和OnResultExecuted 方法

  • OnResultExecuting :Called before the action result executes. 在操做结果执行以前调用
  • OnResultExecuted :Called after the action result executes. 在操做结果执行以后调用

具体代码实现代码以下:

public class ResultFilter : Attribute, IResultFilter { public void OnResultExecuted(ResultExecutedContext context) { // 在结果执行以后调用的操做...
 } public void OnResultExecuting(ResultExecutingContext context) { // 在结果执行以前调用的一系列操做
 } }

4、Asp.Net Core 过滤器的注册方式

这一篇章主要来分析探讨Asp.Net Core 中过滤器的三种注册方式ActionController全局 。

4.1 Action 注册方式

Action 注册方式是局部注册方式,针对控制器中的某个方法上标注特性的方式进行注册,代码以下:

 [AuthonizationFilter()] public IActionResult Index() { return View(); }

4.2 Controller 注册方式

了解过Action 特性注册方式的同窗,必定发现了它的很差之处就是我一个控制器里面须要使用同一套Filter 的时候,须要一个一个Action 标注特性注册,是否是很繁琐呢?有没有其余方式进行代替这些繁琐的操做呢?微软给咱们提供了简便的控制器标注注册方式,代码以下:

[AuthonizationFilter()] public class FirstController : Controller { private ILogger<FirstController> _logger; public FirstController(ILogger<FirstController> logger) { _logger = logger; } public IActionResult Index() { return View(); } }

4.3 全局注册方式

如今有些同窗考虑了一些全局的状况,好比我要全局处理系统中的异常,或者收集操做日志等,须要全局注册一个ExceptionFilter 来实现,就不须要每个Controller 中进行代码注册,方便快捷。代码以下:

public void ConfigureServices(IServiceCollection services) { //全局注册异常过滤器
            services.AddControllersWithViews(option=> { option.Filters.Add<ExecptionFilter>(); }); services.AddSingleton<ISingletonService, SingletonService>(); }

4.4 TypeFilter 和 ServiceFilter 注册方式

上面的五大过滤器中事例代码中其中有一个过滤器的代码比较特别,再来回顾ExceptionFilter过滤器的实现代码:

public class ExecptionFilter : Attribute, IExceptionFilter { private ILogger<ExecptionFilter> _logger; //构造注入日志组件
        public ExecptionFilter(ILogger<ExecptionFilter> logger) { _logger = logger; } public void OnException(ExceptionContext context) { //日志收集
            _logger.LogError(context.Exception, context?.Exception?.Message??"异常"); } }

从上面的代码中能够发现 ExceptionFilter 过滤器实现中存在日志服务的构造函数的注入,也就是说该过滤器依赖于其余的日志服务,可是日志服务都是经过DI 注入进来的;再来回顾下上面Action 注册方式或者Controller 注册方式 也即Attribute 特性标注注册方式,自己基础的特性是不支持构造函数的,是在运行时注册进来的,那要解决这种自己须要对服务依赖的过滤器须要使用 TypeFilter 或者ServiceFilter 方式进行过滤器的标注注册。

TypeFilter 和ServiceFilter 的区别。

  • ServiceFilter和TypeFilter都实现了IFilterFactory
  • ServiceFilter须要对自定义的Filter进行注册,TypeFilter不须要
  • ServiceFilter的Filter生命周期源自于您如何注册,而TypeFilter每次都会建立一个新的实例

TypeFilter 使用方式

代码以下:

[TypeFilter(typeof(ExecptionFilter))] public IActionFilter Index2() { return View(); }

经过上面的代码能够发现AuthonizationFilter 是默认的构造器,可是若是过滤器中构造函数中存在参数,须要注入服务那该怎么办呢?,好比上面的ExceptionFilter 代码,就不能使用这种方式进行注册,须要使用服务特性的方式,咱们能够选择使用 代码以下:

[TypeFilter(typeof(ExecptionFilter))] public IActionFilter Index2() { return View(); }

ServiceFilter 使用方式

控制器中的代码以下:

[ServiceFilter(typeof(ExecptionFilter))] public IActionFilter Index2() { return View(); }

注册服务的代码以下:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) { Console.WriteLine("ConfigureServices"); services.AddControllersWithViews(); //services.AddControllersWithViews(option=> { // option.Filters.Add<ExecptionFilter>(); //}); //注册过滤器服务,使用ServiceFilter 方式必需要注册 不然会报没有注册该服务的相关异常
        services.AddSingleton<ExecptionFilter>(); }

若是你以为还不错,就请点个赞吧,谢谢。

参考博客:

博客:https://www.cnblogs.com/jlion/p/12394949.html

知乎:https://zhuanlan.zhihu.com/p/112507159

相关文章
相关标签/搜索