Asp.Net Core Filter 深入浅出的那些事-AOP

一、前言

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

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

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

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

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

二、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。

三、五大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 接口要求实现OnActionExecutedOnActionExecuting 方法

    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){// 在结果执行之前调用的一系列操作}}

四、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 方式进行过滤器的标注注册。

TypeFilterServiceFilter 的区别。

  • 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>();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++函数模板和普通函数的调用规则

C函数模板和普通函数的调用规则: 普通函数可以进行自动类型转换。 函数模板必须严格类型匹配。 C编译器优先考虑普通函数。 如果函数模板可以产生一个更好的匹配&#xff0c;那么选择模板。 可以通过空模板实参列表的语法限定编译器只能通过模板匹配。 代码如下&#xff…

A Mini Locomotive POJ - 1976(动态规划+思维)

题意&#xff1a;有三个火车头&#xff0c;n个车厢&#xff0c;每个车厢里面对应的有一定的人数。规定每个火车头最多 拉m个连续的车厢而且他们拉的车厢一定是从左到右连续的&#xff0c;问它能够拉的最多的人数&#xff1b; 思路&#xff1a;类似01背包的解法&#xff0c;首先…

mysql如何管理innodb元数据_MySQL 8 InnoDB 集群管理

使用 dba.checkInstanceConfiguration()在添加实例到集群中前&#xff0c;使用该方法检查实例配置是否满足InnoDB 集群要求。使用 dba.configureLocalInstance() 配置实例在MySQL Server版本不支持持久化功能的实例上&#xff0c;需要使用该方法添加修改配置信息到本地实例的选…

c编译过程概述

index.cpp是如何变成index.exe&#xff1f; 过程如下: #mermaid-svg-TCJ1Rm4qFgAObpkX .label{font-family:trebuchet ms, verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-TCJ1Rm4qFgAObpkX .label text{fill:#333}#mermaid-svg-T…

.NET Core技术研究-通过Roslyn代码分析技术规范提升代码质量

随着团队越来越多&#xff0c;越来越大&#xff0c;需求更迭越来越快&#xff0c;每天提交的代码变更由原先的2位数&#xff0c;暴涨到3位数&#xff0c;每天几百次代码Check In&#xff0c;补丁提交&#xff0c;大量的代码审查消耗了大量的资源投入。如何确保提交代码的质量和…

FATE HDU - 2159(二维完全背包)

限制条件&#xff1a; 1.忍耐度 m 2.杀怪个数 s 构造&#xff1a; dp[m][s] 得到的经验值 Time limit 1000 ms Memory limit 32768 kB OS Windows Source 2008信息工程学院集训队——选拔赛 最近xhd正在玩一款叫做FATE的游戏&#xff0c;为了…

mysql数据库check命令_利用mysqlcheck命令快速修复mysql数据库

表索引异常,修复msql表索引(表引擎:myisam)myisamchk --safe-recover /usr/local/mysql/data/ename_news/dede_arccacherepair table customerquestion;Error infos: Table ./ename_news/dede_arccache is marked as crashed and should be repairedmyisamchk -r data/ename_ne…

python中类变量的访问方式_在Python中,如何访问类方法中的“静态”类变量

就像所有的好例子一样&#xff0c;你简化了你实际想要做的事情。这很好&#xff0c;但值得注意的是&#xff0c;python在类和实例变量方面有很大的灵活性。方法也是如此。为了获得很好的可能性&#xff0c;我建议阅读Michael Ftsch new-style classes introduction&#xff0c;…

[PAT乙级]1009 说反话

给定一句英语&#xff0c;要求你编写程序&#xff0c;将句中所有单词的顺序颠倒输出。 输入格式&#xff1a; 测试输入包含一个测试用例&#xff0c;在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成&#xff0c;其中单词是由英文字母&#xff08;大小写…

Cheapest Palindrome POJ - 3280(动态规划*)

题意&#xff1a; 给出一个字符串&#xff0c;要求将其修改成一个回文字符串&#xff0c;给出修改某种字母&#xff08;添加或删除&#xff09;的价值&#xff0c;求最小使其成为回文字符串的价值。 题解&#xff1a; 感觉是求最长回文子序列的变形&#xff0c;然而刚开始想着…

Blazor Blazor Blazor

Blazor 项目现在可以说是整个 .NET 社区最火的项目&#xff0c;但是它的起源却非常有趣&#xff0c;也可以说是见证了 .NET 社区的发展。2017年4月&#xff0c;一位英国光头小哥哥开始思考在 WebAssembly 下运行 .NET 的方法&#xff0c;这时他碰巧发现一个之前从未见过的 .NET…

C++函数模板机制结论

函数模板机制结论: 编译器并不是把函数模板处理成能够处理任何类型的函数函数模板通过具体类型产生不同的函数编译器会对函数模板进行两次编译&#xff0c;在声明的地方对模板代码本身进行编译&#xff0c;在调用的地方对参数替换后的代码进行编译。

python最大堆heapq_Python-堆的实现与heapq(最小堆库函数)

目录简介堆是一个二叉树&#xff0c;它的每个父节点的值都只会小于或大于所有孩子节点(的值)。它使用了数组来实现&#xff1a;从零开始计数&#xff0c;对于所有的 k &#xff0c;都有 heap[k] < heap[2*k1] 和 heap[k] < heap[2*k2]。 为了便于比较&#xff0c;不存在的…

深入浅出 ASP.NET Core 与 Docker 入门课程说明

点击蓝字“角落的白板报”关注我哟加个“星标★”&#xff0c;好文必达&#xff01;深入浅出 ASP.NET Core 与 Docker 入门课程说明《深入浅出 ASP.NET Core 与 Docker 》是一门新的课程&#xff0c;本课程所有的内容全部免费&#xff0c;以图文配合视频的形式呈现。课程完整视…

UVA10129 Play on Words (并查集判连通+欧拉回路)

题目解析&#xff1a; 输入一些英文单词&#xff0c;根据该单词的首尾字母&#xff0c;判断所有单词能不能连成一串&#xff0c; 类似于成语接龙的意思。同样如果有多个重复的单词时&#xff0c;也必须满足这样的条件才能通过&#xff0c; 否则都是不可能的情况。输入包括若干…

[PAT乙级]1010 一元多项式求导

设计函数求一元多项式的导数。&#xff08;注&#xff1a;x​n​​&#xff08;n为整数&#xff09;的一阶导数为nx​n−1​​。&#xff09; 输入格式: 以指数递降方式输入多项式非零项系数和指数&#xff08;绝对值均为不超过 1000 的整数&#xff09;。数字间以空格分隔。 …

python注入进程_向进程中注入Python代码

我想把Python代码注入到一个进程中&#xff0c;当它注入时&#xff0c;它似乎会使我的进程崩溃。我没有在我自己的程序中得到任何错误&#xff0c;但目标进程停止工作。被调用的非托管api没有给我任何错误&#xff0c;并且似乎已经正确地执行了它们的执行。在[DllImport("…

微软将在新西兰建设其第一个数据中心区域

昨天新西兰各IT群都被一条消息刷屏了&#xff1a;详情可见&#xff1a;https://news.microsoft.com/en-nz/2020/05/06/aotearoa-disclosure/NZ的第一个Azure region region 是云计算的一个术语&#xff0c;也就是各大云运营商机房部署的位置。目前微软、亚马逊、谷歌等比较大的…

Sorting It All Out (易错题+拓扑排序+有向图(判环+判有序)优先级)

这道题目考察了拓扑排序的基本思想&#xff1a;每一步寻找一个入度为0的结点&#xff0c;然后 删除之。将这个结点指向的结点入度减1。删除从这个结点出发的所有边 同时考察了对于一个有向图是否有环、是否严格有序的判断。&#xff08;当发现多个结点的度 为0时&#xff0c;则…

[PAT乙级]1011 A+B 和 C

给定区间 [−2​31​​,2​31​​] 内的 3 个整数 A、B 和 C&#xff0c;请判断 AB 是否大于 C。 输入格式&#xff1a; 输入第 1 行给出正整数 T (≤10)&#xff0c;是测试用例的个数。随后给出 T 组测试用例&#xff0c;每组占一行&#xff0c;顺序给出 A、B 和 C。整数间以…