我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ASP.NET Core MVC 过滤器(Filter)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ASP.NET Core MVC 过滤器(Filter)

一.过滤器如何工作

  不同的过滤器类型在管道中的不同阶段执行,因此具有各自的与其场景。根据需要执行的任务以及需要执行的请求管道中的位置,选择要创建的过滤器类型。过滤器在 MVC 操作调用管道中运行,有时也称为过滤管道,在 MVC 中选择要执行的操作后,执行操作上的过滤器,如图:

  不同的过滤器在管道内的不同位置执行。像授权过滤器这样的过滤器只在管道中靠前的位置执行。其他过滤器,如操作(Action)过滤器,可以在管道执行的其他部分之前和之后执行,如图:

1.选择过滤器

  授权过滤器用于确定当前请求用户是否被授权。

  资源过滤器是在授权之后第一个处理请求的过滤器,也是最后一个在请求离开过滤管道时接触请求的过滤器。在性能方面,对实现缓存或者对过滤管道进行短路 特别有用。

  操作过滤器包装对单个操作方法的调用,并且可以处理传递到操作的参数以及从操作返回的操作结果。

  异常过滤器用于对 MVC 应用程序中未处理的异常应用全局策略。

  结果过滤器包装单个操作结果的执行,并且尽在操作执行成功时运行。它们必须是围绕视图执行或格式化程序执行的逻辑的理想选择。 

2.实现过滤器

  所有过滤器均可通过不同的接口定义支持同步和异步的实现。根据需要执行的任务类型,选择同步或异步实现。从框架的角度看,它们是可以互换的。

  同步过滤器定义了 OnStageExecuting OnStageExecuted 方法(也有例外)。OnStageExecuting 方法在事件管道阶段之前通过阶段名称来调用,而 OnStageExecuted 方法将在阶段名称命名的管道阶段之后调用。


 public class SampleActionFilter:IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            //操作执行前做的事情
        }
        public void OnActionExecuted(ActionExecutedContext context)
        {
            //操作执行后做的事情
        }
    }

  异步过滤器定义了一个单一的 OnActionExecutionAsync  方法,可以在具体管道阶段的前后运行。 OnActionExecutionAsync 方法提供了一个 ActionExecutionDelegate 委托,调用时该委托会执行具体管道阶段的工作,然后等待完成。


public class SampleAsyncActionFilter: IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            //操作执行前做的事情
            await next();
            //操作执行后做的事情
        }
    }

3.过滤器作用域

  过滤器有三种不同级别的作用域。你可以在特定的操作上用特性(Attribute)的方式使用特定的过滤器。也可以在控制器上用特性的方式使用过滤器,这样就可以将效果作用在控制器内的所有操作上。或者注册一个全局过滤器,它将作用于整个 MVC 应用程序的每一个操作。

  如果想要使用全局过滤器,可以在配置 MVC 时,在 Startup ConfigureServices 方法中添加:


services.AddMvc(options =>
            {
                options.Filters.Add(typeof(SampleActionFilter));//通过类型
                options.Filters.Add(new SampleActionFilter());//注册实例
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);


  过滤器既可以通过类型添加,也可以通过实例添加。如果通过实例添加,则该实例会被使用于每一个请求。如果通过类型添加,则在每次请求后都会创建一个实例,其所有构造函数依赖项都将通过 DI 来填充。

  把过滤器接口的实现当作特性使用也非常方便。过滤器特性可应用于控制器和操作方法。框架包含了内置的基于特性的过滤器,可以继承他们或者另外定制。例如,下面的过滤器继承了 ResultFilterAttribute,并重写 OnResultExecuting 方法(在响应中增加一个信息头): 


public class AddHeaderAttribute: ResultFilterAttribute
    {
        private readonly string _name;
        private readonly string _value;

        public AddHeaderAttribute(string name, string value)
        {
            _name = name;
            _value = value;
        }

        public override void OnResultExecuting(ResultExecutingContext context)
        {
            context.HttpContext.Response.Headers.Add(
                _name,new string[] { _value });
            base.OnResultExecuting(context);
        }
    }

  特性允许过滤器接受参数,如下,可将此特性添加到控制器或操作中,并为其指定所需 HTTP 头的名称和值:

[AddHeader("Author", "Ruby Lu")]
 public class HomeController : Controller
{
}

以下几种过滤器接口可以自定义为相应特性的实现:

  • ActionFilterAttribute
  • ExceptionFilterAttribute
  • ResultFilterAttribute
  • FormatFilterAttribute
  • ServiceFilterAttribute
  • TypeFilterAttribute

 4.取消和短路

  通过设置传入过滤器方法的上下文参数中的 Result 属性,可以在过滤器管道的任意一点短路管道。比如,下面的 ShortCircuitingResourceFilter 将阻止它之后管道内的所有过滤器,包括所有操作过滤器:


public class ShortCircuitingResourceFilter:Attribute,IResourceFilter
    {
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            context.Result = new ContentResult() {
                Content = "短路"
            };
        }

        public void OnResourceExecuted(ResourceExecutedContext context)
        {

        }
    }

二.配置过滤器

  全局过滤器在 Startup 中配置。基于特性的过滤器如果不需要任何依赖,可以简单地继承一个已存在地过滤器相对应地特性类型。如果要创建一个非全局作用域,但需要从依赖注入中获得依赖项的过滤器,那么在它们上面加上 ServiceFilterAttribute TypeFilterAttribute 特性,这样就可用于控制器或操作了。

1.依赖注入

  以特性形式实现的,直接添加到控制器或操作的过滤器,其构造函数不得由依赖注入提供依赖项。其原因在于,特性所需的构造函数参数必须由使用处直接提供。这是特性原型机理的限制。

  如果过滤器需要从 DI 中获得依赖项,那么可以用以下几种方法在类或操作方法使用:

  • ServiceFilterAttribute
  • TypeFilterAttribute
  • IFilterFactory 实现特性

  TypeFilter 将为其依赖项从 DI 中使用服务来实例化一个实例。 ServiceFilter 则从 DI 中获取一个过滤器实例。下面演示 ServiceFilter

  先在 ConfigureServices 中注册 AddHeaderFilterWithDI 类型:services.AddScoped<AddHeaderFilterWithDI>();

然后使用:


   [ServiceFilter(typeof(AddHeaderFilterWithDI))]

    public IActionResult Index()

    {  

    }

  ServiceFilterAttribute 实现了IFilterFactory 接口,它公开了一个创建 IFilter 实例的方法。在 ServiceFilterAttribute 中,IFilterFactory 接口的 CreateInstance 方法被实现为从服务容器加载指定的类型。

  TypeFilterAttribute 非常类似 ServiceFilterAttribute (也实现 IFilterFactory 接口),但它的类型不是直接从 DI 容器中解析,相反,它使用 Microsoft.Extensions.DependencyInjection.ObjectFactory 实例化类型。

  由于这种差异,使用 TypeFilterAttribute 引用的类型不需要在使用前向容器注册,但它们仍由容器来填充其依赖项。此外,TypeFilterAttribute 可以可选的接受该类型的构造函数参数。下面是 TypeFilterAttribute 演示:

  


      [TypeFilter(typeof(AddHeaderAttribute),Arguments =new object[] { "Author","Ruby" })]
        public IActionResult Index()
        {
            return View();
        }

   如果有一个简单的过滤器,不需要任何参数,但有构造函数需要通过 DI 填充依赖项,那么可以继承 TypeFilterAttribute,允许使用自己命名的特性类和方法(而不是 [TypeFilterAttribute(typeof(FilterType))])。下面的过滤器显示了如何实现此功能:


 public class SampleActionFilterAttribute:TypeFilterAttribute
    {
        public SampleActionFilterAttribute() : base(typeof(SampleActionFilterImpl))
        {
        }
        private class SampleActionFilterImpl:IActionFilter
        {
            public void OnActionExecuting(ActionExecutingContext context)
            {
                //操作执行前做的事情
            }
            public void OnActionExecuted(ActionExecutedContext context)
            {
                //操作执行后做的事情
            }
        }
    }

  该过滤器可通过使用 [SampleActionFilter] 这样的语法应用于类或方法,而不必使用 [TypeFilter] 或 [ServiceFilter] 。

  IFilterFactory 实现 IFilter ,因此在过滤器管道中,任何位置的  IFilterFactory 实例都可当作 Filter 实例来使用。当框架准备调用过滤器时,将尝试将其转换为 IFilterFactory 。如果转换成功, 则调用 CreateInstance 方法来创建将被调用的 IFilter 实例。这是一种非常灵活的设计,因为当应用程序启动时,不需要明确地设置精确地过滤器。

  你可以在自己地特性中实现 IFilterFactory 几口,作为另一种创建过滤器的方法:


public class AddHeadWithFactoryAttribute:Attribute, IFilterFactory
    {
        public bool IsReusable { get; }
        //实现IFilterFactory
        public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
        {
            return new InternalAddHeaderFilter();
        }
    }

    public class InternalAddHeaderFilter : IResultFilter
    {
        public  void OnResultExecuting(ResultExecutingContext context)
        {
            context.HttpContext.Response.Headers.Add(
                "Internal", new string[] { "Header Add" });
        }
        public void OnResultExecuted(ResultExecutedContext context)
        {

        }
    }

 

2.排序

   过滤器可以应用于操作方法或控制器(通过特性)或添加到全局过滤器集合中。作用域通常也决定了排序,最接近操作的过滤器首先运行。

  除了作用域,过滤器还可以通过实现 IOrderedFilter 来重写它们的执行顺序。此接口简单的暴露了一个 int Order 属性,并且过滤器基于该属性以数字升序执行。所有内置的过滤器,包括 TypeFilterAttribute ServiceFilterAttribute ,都实现 IOrderedFilter  接口。,因此当将过滤器特性应用于类或方法时,可以指定过滤器执行顺序。默认情况下,所有内置过滤器的 Order 属性都为0,因此范围用作分隔符,并且是决定性因素(除非 Order 设置为 0)。

  每个从 Controller 基类继承的控制器都包含 OnActionExecuting OnActionExecuted 方法。这些方法为给定操作包装了过滤器,它们分别最先运行和最后运行。假设没有为任何过滤器设置 Order 舒总,那么单纯基于范围的顺序为:

  • 控制器的 OnActionExecuting
  • 全局过滤器的OnActionExecuting
  • 类过滤器的OnActionExecuting
  • 方法过滤器的OnActionExecuting
  • 方法过滤器的OnActionExecuted
  • 类过滤器的OnActionExecuted
  • 全局过滤器的OnActionExecuted
  • 控制器过滤器的OnActionExecuted

   要修改默认的基于范围的顺序,则应显示设置类级别或者方法级别过滤器的 Order 属性。例如,将 Order = -1 添加到方法级属性:


  [MyFilter (Name = "...",Order = -1)]

在这种情况下,小于零的值将确保此过滤器在全局和类级过滤器之前运行:

  • 控制器的 OnActionExecuting
  • 方法过滤器的OnActionExecuting
  • 全局过滤器的OnActionExecuting
  • 类过滤器的OnActionExecuting
  • 类过滤器的OnActionExecuted
  • 全局过滤器的OnActionExecuted
  • 控制器过滤器的OnActionExecuted
  • 方法过滤器的OnActionExecuted

  Controller 类的方法总是在所有过滤器之前和之后运行。这些方法不作为IFilter实例实现。也不参与IFilter排序算法。

 3.对比中间件

  一般来说,过滤器用于处理业务与应用程序的横切关注点,用法和功能很像中间件,但过滤器允许你将作用范围缩小,并将其插入到应用程序中有意义的位置,例如视图之前或模型绑定之后。过滤器是 MVC 的一部分,可以访问其上下文和构造函数。例如,中间件很难检测到请求的模型验证是否产生错误,并且做出相应的响应。

到此这篇关于ASP.NET Core MVC 过滤器(Filter)的文章就介绍到这了,更多相关ASP.NET Core MVC 过滤器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ASP.NET Core MVC 过滤器(Filter)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

ASP.NET Core MVC中怎么实现过滤器

本篇内容介绍了“ASP.NET Core MVC中怎么实现过滤器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!过滤器如何工作?过滤器在 MV
2023-06-29

ASP.NET Core MVC过滤器运行流程解析

ASP.NETCoreMVC过滤器在请求和响应管道中运行,用于增强应用程序行为。过滤器包括:验证用户权限的AuthorizeFilter,在action前后执行的ActionFilter,在action返回结果前后执行的ResultFilter,在发生异常时执行的ExceptionFilter。过滤器可以按顺序应用,并可以通过特性、全局注册或依赖注入进行应用,从而实现灵活的请求和响应处理。
ASP.NET Core MVC过滤器运行流程解析
2024-04-02

ASP.NET MVC授权过滤器如何使用

这篇文章主要介绍“ASP.NET MVC授权过滤器如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“ASP.NET MVC授权过滤器如何使用”文章能帮助大家解决问题。过滤器过滤器(Filter)
2023-06-29

聊一聊Asp.net过滤器Filter那一些事

最近在整理优化.net代码时,发现几个很不友好的处理现象:登录判断、权限认证、日志记录、异常处理等通用操作,在项目中的action中到处都是。在代码优化上,这一点是很重要着力点。这时.net中的过滤器、拦截器(Filter)就派上用场了。现
2022-06-07

ASP.NET MVC过滤器执行顺序是什么

小编给大家分享一下ASP.NET MVC过滤器执行顺序是什么,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!规则一:不同类型的过滤器有一个先后顺序即执行顺序是:授权过滤器->动作过滤器->结果过滤器->异常过滤器。注意:如果
2023-06-29

java过滤器中Filter的ChainFilter过滤链

在Java过滤器中,FilterChain是一种过滤链,用于按照一定顺序依次调用多个过滤器对请求进行处理。FilterChain接口定义了一个doFilter方法,该方法接受ServletRequest和ServletResponse作为参
2023-08-11

Java过滤器Filter详解

目录Filter学习Filter功能Filter的工作原理多个Filter的实现Filter的执行逻辑总结Filter学习Filter功能 拦截jsp、静态图片文件、静态html资源文件 实现URL级别的权限访问控制 过滤敏感词汇 压缩
2019-04-25

HBase Filter 过滤器概述

abc过滤器介绍HBase过滤器是一套为完成一些较高级的需求所提供的API接口。过滤器也被称为下推判断器(push-down predicates),支持把数据过滤标准从客户端下推到服务器,带有 Filter 条件的 RPC 查询请求会把 Filter 分发到
HBase Filter 过滤器概述
2019-09-14

servlet过滤器(Filter)详解(九)

本文实例为大家分享了servlet过滤器的具体代码,供大家参考,具体内容如下1.servlet过滤器产生背景  项目中我们会遇到这样一类的需求,对访问服务器的用户ip实施过滤,只有在允许名单中的ip才能访问服务,为了实现需求,每当有客户端请
2023-05-31

详解Servlet之过滤器(Filter)

过滤器1.为什么使用它?有很多全站性的东西需要处理,例如乱码问题,通过过滤器统一进行过滤更简单2.有什么用?实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以
2023-05-31

HBase Filter 过滤器之 DependentColumnFilter 详解

前言:本文详细介绍了 HBase DependentColumnFilter 过滤器 Java&Shell API 的使用,并贴出了相关示例代码以供参考。DependentColumnFilter 也称参考列过滤器,是一种允许用户指定一个参考列或引用列来过滤其
HBase Filter 过滤器之 DependentColumnFilter 详解
2022-03-14

HBase Filter 过滤器之FamilyFilter详解

前言:本文详细介绍了 HBase FamilyFilter 过滤器 Java&Shell API 的使用,并贴出了相关示例代码以供参考。FamilyFilter 基于列族进行过滤,在工作中涉及到需要通过HBase 列族进行数据过滤时可以考虑使用它。比较器细节及
HBase Filter 过滤器之FamilyFilter详解
2017-01-24

java filter过滤器怎么使用

在 Java 中使用过滤器(Filter)需要以下步骤:1. 创建一个类并实现 javax.servlet.Filter 接口。该接口定义了三个方法:init、doFilter 和 destroy。2. 在 init 方法中进行过滤器的初始
2023-09-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录