ASP.NET Core MVC 从入门到精通之Filter

news2024/12/26 10:38:58

随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,或其他想从事ASP.NET Core MVC 系统开发的人员。

经过前几篇文章的讲解,初步了解ASP.NET Core MVC项目创建,启动运行,以及命名约定,创建控制器,视图,模型,接收参数,传递数据ViewData,ViewBag,路由,页面布局,wwwroot和客户端库,Razor语法,EnityFrameworkCore与数据库,HttpContext,Request,Response,Session,序列化,文件上传,自动映射,Html辅助标签,模型校验,鉴权、授权基础,Identity入门,日志管理等内容,今天继续讲解ASP.NET Core MVC 中Filter(筛选器)等相关内容,仅供学习分享使用。

什么是Filter?

Filter又称为筛选器,过滤器。在ASP.NET Core MVC项目中,通过使用Filter,可以在请求处理管道的特定位置之前或之后运行代码。可以创建自定义Filter,用于处理横切关注点,类似于AOP面向切面编程。对于创建Filter,可以减少代码的复制,例如,错误处理异常筛选器可以合并错误处理。

Filter工作原理

从请求开始,到请求结束,经过一系列的节点,组成了调用管道。Filter在ASP.NET Core MVC的调用管道内运行,过滤器相当于在管道中设置的几个钩子,用于执行特定的代码。

Filter类型

根据不同的处理功能,筛选器主要分为以下几类:

  • 授权筛选器AuthorizationFilter:

    • 首先运行。
    • 确定用户是否获得请求授权。
    • 如果请求未获授权,可以让管道短路。
  • 资源筛选器Resource Filter:

    • 授权后运行。
    • OnResourceExecuting 在筛选器管道的其余阶段之前运行代码。 例如,OnResourceExecuting 在模型绑定之前运行代码。
    • OnResourceExecuted 在管道的其余阶段完成之后运行代码。
  • 操作筛选器Action Filter:

    • 在调用操作方法之前和之后立即运行。
    • 可以更改传递到操作中的参数。
    • 可以更改从操作返回的结果。
    • 不可在 Razor Pages 中使用。
  • 异常筛选器Exception Filter:在向响应正文写入任何内容之前,对未经处理的异常应用全局策略。

  • 结果筛选器Result Filter:

    • 在执行操作结果之前和之后立即运行。
    • 仅当操作方法成功执行时才会运行。
    • 对于必须围绕视图或格式化程序的执行的逻辑,会很有用。

 下图展示了Filter筛选器类型在筛选器管道中的交互方式:

Filter实现

所有的Filter都实现接口IFilterMetadata,根据不同的业务类型,派生出了五个接口,分别对应五大类Filter,如下所示:

注意:上述五个接口还有对应异步接口(Async)。

Filter作用域

Filter可以作用在Controller,Action,全局。下面的示例阐释了为同步操作筛选器运行筛选器方法的顺序:

授权Filter

授权筛选器:

  • 是筛选器管道中运行的第一个筛选器。
  • 控制对操作方法的访问。
  • 具有在它之前的执行的方法,但没有之后执行的方法。

如常用的RequireHttps就是授权筛选器,它实现了IAuthorizationFilter接口,并继承了Attirbute,所以可以作用于Controller或Action中。以限制请求的方式。

using Microsoft.AspNetCore.Mvc.Filters;
using System;

namespace Microsoft.AspNetCore.Mvc
{
    //
    // 摘要:
    //     An authorization filter that confirms requests are received over HTTPS.
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class RequireHttpsAttribute : Attribute, IAuthorizationFilter, IFilterMetadata, IOrderedFilter
    {
        public RequireHttpsAttribute();

        public int Order { get; set; }

        public virtual void OnAuthorization(AuthorizationFilterContext filterContext);

        protected virtual void HandleNonHttpsRequest(AuthorizationFilterContext filterContext);
    }
}

资源Filter

资源Filter在授权Filter之后执行,需要实现IResourceFilter接口。如下所示:

using Microsoft.AspNetCore.Mvc.Filters;

namespace DemoCoreMVC.Filter
{
    /// <summary>
    /// 同步版本
    /// </summary>
    public class LogResourceFilter :Attribute, IResourceFilter
    {
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            //Action执行完成后执行
            Console.WriteLine("********************On Resource Filter Executed********************");
        }

        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            //授权Filter执行后执行。
            Console.WriteLine("********************On Resource Filter Executing********************");
        }
    }

    /// <summary>
    /// 异步版本
    /// </summary>
    public class AsynLogResouceFilter : Attribute, IAsyncResourceFilter
    {
        public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            Console.WriteLine("********************On Aysnc Resource Filter Executing********************");
            var exceutedContext =  await next();
            Console.WriteLine("********************On Async Resource Filter Executed********************");
        }
    }
}

如果要使大部分管道短路,资源筛选器会很有用。 例如,如果缓存命中,则缓存筛选器可以绕开管道的其余阶段。

操作Filter

操作筛选器不应用于 Razor Pages。 Razor Pages 支持 IPageFilter 和 IAsyncPageFilter。

操作筛选器:

  • 实现 IActionFilter 或 IAsyncActionFilter 接口。
  • 它们的执行围绕着操作方法的执行。

以下代码显示示例操作筛选器:

using Microsoft.AspNetCore.Mvc.Filters;

namespace DemoCoreMVC.Filter
{
    public class DoDoActionFilter : Attribute, IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {

            Console.WriteLine("********************On Action Executed********************");
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            Console.WriteLine("********************On Action Executing********************");
        }
    }

    public class AsyncDoDoActionFilter : IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {

            Console.WriteLine("********************On Async Action Executing********************");
            await next();
            Console.WriteLine("********************On Async Action Executed********************");
        }
    }
}

ActionExecutingContext 提供以下属性:

  • ActionArguments - 用于读取操作方法的输入。
  • Controller - 用于处理控制器实例。
  • Result - 设置 Result 会使操作方法和后续操作筛选器的执行短路。

ActionExecutedContext 提供 Controller 和 Result 以及以下属性:

  • Canceled - 如果操作执行已被另一个筛选器设置短路,则为 true。
  • Exception - 如果操作或之前运行的操作筛选器引发了异常,则为非 NULL 值。 将此属性设置为 null:
    • 有效地处理异常。
    • 执行 Result,从操作方法中将它返回。

对于 IAsyncActionFilter,一个向 ActionExecutionDelegate 的调用可以达到以下目的:

  • 执行所有后续操作筛选器和操作方法。
  • 返回 ActionExecutedContext

异常Filter

异常筛选器:

  • 实现 IExceptionFilter 或 IAsyncExceptionFilter。
  • 可用于实现常见的错误处理策略。

下面的异常筛选器示例显示在开发应用时发生的异常的相关详细信息:

using Microsoft.AspNetCore.Mvc.Filters;

namespace DemoCoreMVC.Filter
{
    public class DoExceptionFilter :Attribute, IExceptionFilter
    {
        public void OnException(ExceptionContext context)
        {
            Console.WriteLine("********************On Exception********************");
        }
    }

    public class DoAsyncExceptionFilter : Attribute, IAsyncExceptionFilter
    {
        public async Task OnExceptionAsync(ExceptionContext context)
        {
            await Task.Run(() =>
            {
                Console.WriteLine("********************On Exception Async********************");
            });

        }
    }
}

异常筛选器:

  • 没有之前和之后的事件。
  • 实现 OnException 或 OnExceptionAsync。
  • 处理 Razor 页面或控制器创建、模型绑定、操作筛选器或操作方法中发生的未经处理的异常。
  • 请不要捕获资源筛选器、结果筛选器或 MVC 结果执行中发生的异常。

若要处理异常,请将 ExceptionHandled 属性设置为 true 或分配 Result 属性。 这将停止传播异常。 异常筛选器无法将异常转变为“成功”。 只有操作筛选器才能执行该转变。

异常筛选器:

  • 非常适合捕获发生在操作中的异常。
  • 并不像错误处理中间件那么灵活。

建议使用中间件处理异常。 基于所调用的操作方法,仅当错误处理不同时,才使用异常筛选器。 例如,应用可能具有用于 API 终结点和视图/HTML 的操作方法。 API 终结点可以将错误信息返回为 JSON,而基于视图的操作可能会以 HTML 形式返回错误页。

结果Filter

结果筛选器:

  • 实现接口:
    • IResultFilter 或 IAsyncResultFilter
    • IAlwaysRunResultFilter 或 IAsyncAlwaysRunResultFilter
  • 它们的执行围绕着操作结果的执行。
using Microsoft.AspNetCore.Mvc.Filters;

namespace DemoCoreMVC.Filter
{
    public class DoResultFilter :Attribute, IResultFilter
    {
        public void OnResultExecuted(ResultExecutedContext context)
        {
            Console.WriteLine("********************On Result Executed********************");
        }

        public void OnResultExecuting(ResultExecutingContext context)
        {
            Console.WriteLine("********************On Result Executing********************");
        }
    }

    public class DoAysncResultFilter :Attribute, IAsyncResultFilter
    {
        public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
        {
            Console.WriteLine("********************On Result Execution Async Executing********************");
            await next();
            Console.WriteLine("********************On Result Execution Async Executed********************");
        }
    }

}

Filter测试

将写好的过滤器,放在Home/Index上,如下所示:

[DoExceptionFilter]
[LogResourceFilter]
[DoResultFilter]
[DoDoActionFilter]
public IActionResult Index()
{
    _logger.LogInformation("Hello, 这是首页!");
    return View();
}

测试如下所示:

说明:异常过滤器没有输出内容,是因为没有异常产生。授权过滤器没有添加,在所有过滤器之前开始,所有过滤器之后结束。

Filter全局应用

Filter可以应用在单个Controller或Action上,也可以进行全局应用,代码如下所示:

builder.Services.AddControllersWithViews(option =>
{
    option.Filters.Add<LogResourceFilter>();
    option.Filters.Add<DoExceptionFilter>();
    option.Filters.Add<DoResultFilter>();
    option.Filters.Add<DoDoActionFilter>();
});

全局测试如下所示:

以上就是ASP.NET Core MVC 从入门到精通之Filter的全部内容。

参考文档

官方文档:https://learn.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters?view=aspnetcore-6.0

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

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

相关文章

【数据分享】1929-2022年全球站点的逐月降雪深度数据(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 对于具体到监测站点的气象数据&#xff0c;之前我们分享过1929-2022年全球气象…

JavaScript排序sort()方法(解决null、undefined、0之间的排序(混乱)问题)

问题&#xff1a; 如果数组内某一对象为空值&#xff0c;排序是怎样的呢&#xff1f;(显然并不是按年龄顺序排序的&#xff0c;因为存在null和undefined) var arr[{"age":24,name:zs},{"age":0,name:ls},{"age":0,name:gr}&#xff0c;{"…

数据结构算法 -分而治之算法

引言 坤坤是一个养鸡场的员工&#xff0c;他非常热爱他的工作&#xff0c;并且总是努力提高他的专业技能。有一天&#xff0c;养鸡场接到了一项任务&#xff1a;在短时间内处理一批大量的鸡。 这批鸡数量非常大&#xff0c;比普通的数量要多得多&#xff0c;坤坤意识到他们需…

作业(Job)——OS

目录 1、批处理作业 2、交互式作业 小结&#xff1a;作业、进程、线程 作业概念 &#xff1a;用户要求计算机系统为其完成的计算任务集合。 作业步&#xff08;job step) &#xff1a;作业处理过程中一个相对独立的步骤 一般一个作业步可由一个进程完成某些作业步之间可以并…

2023世界人工智能大会-图技术高峰论坛重磅来袭!邀您共同参与!

2023年7月6-8日&#xff0c;一年一度的世界人工智能大会&#xff08;WAIC&#xff09;即将拉开帷幕。创邻科技作为大会的战略合作伙伴&#xff0c;将承办第三届图技术高峰论坛。 过去两届图技术论坛&#xff0c;分别以“大数据关联”和“AI应用”为关键词&#xff0c;邀请图技…

基于ChatGPT的端到端语音聊天机器人项目实战(一)

基于ChatGPT的端到端语音聊天机器人项目实战 ChatGPT API后台开发实战 本节主要是跟大家分享一个端到端的基于模型驱动的对话机器人,会有前端和后端,也会有一些具体模型的调用,读者需具有Python语言编程的基础,这是前置性的条件,有了这个基础,理论上讲本节所有的内容,…

Sui Move HackerHouse预热开启,9月大理见

9月3日&#xff0c;Sui Move 主题的 Antalpha HackerHouse 将在大理举办&#xff0c;为期 21 天&#xff0c;向所有 Web3 开发者发出 co-buidling & co-living 邀请。 本期 HackerHouse 由 Antalpha Labs 发起&#xff0c;Sui Foundation赞助&#xff0c;MoveFuns DAO、No…

魔视智能MOTOVIS入选世界经济论坛「2023年度技术先锋」

&#xffee;世界经济论坛&#xff08;World Economic Forum&#xff09;宣布从全球范围内选出了100家最有前途的技术先锋企业&#xff0c;这些企业致力于解决可持续性、气候变化和医疗保健等问题。 &#xffee;作为嵌入式人工智能自动驾驶的推动者&#xff0c;魔视智能MOTOVI…

项目管理,到底管什么?

在以前&#xff0c;项目管理职能单一且明确的时候&#xff0c;大家对项目管理的认知还比较统一&#xff1a;一个项目经理带领一个团队完成一个项目。 而在现在的环境下&#xff0c;尤其是互联网&#xff0c;项目经理的职能和定位以不同公司、不同老板、不同需要而参差不齐&…

制造业数字化转型解决方案

制造业数字化转型解决方案 数字化转型已成为制造业发展的必由之路&#xff0c;要提高生产制造水平&#xff0c;就需要提高对生产运营各环节数据的采集、处理和利用效率。当前的工业数据采集仍存在种种不足&#xff0c;现可以利用具有强大设备接入能力、通信协议转换能力、数据…

多线程(十):总结

本章用来处理一下之前遗漏的很多问题&#xff0c;在多线程那一章&#xff0c;很多常见面试题都没有讲&#xff0c;这里再来补充一下。 HashTable, HashMap, ConcurrentHashMap 之间的区别 HashTable, HashMap, ConcurrentHashMap 都带有Map&#xff0c;它们其实都是 Map 的接…

数据库设计软件Power Designer详解教程(附源码)

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Power Designer概述 Power Designer 是美国Sybase公司的CASE工具集&#xff0c;利用Power Designer可分别从概念数据模型(Conceptual Data Model)和物理数据模型(Physical D…

如何查看某个starter的详细官方文档

\qquad 相信很多小伙伴在用到一个没怎么接触过的starter的时候&#xff0c;也有不知道怎么使用&#xff0c;怎么配置的苦恼&#xff0c;本文介绍一种大部分开源技术都能使用的查看官方文档的方式。 1.首先在github搜索相关技术 \qquad 这里以redis为例&#xff0c;如下&#x…

QT学习之旅 - network连接

文章目录 网络知识点IP地址IPv4和IPv6 端口号(协议端口)端口分类UDP端口和TCP端口 networkpro文件.h文件.cpp文件 UDP连接绑定端口绑定成功后等待对方进行连接点击发送源码扩展: nodejs-udp服务端(用于跟QT程序进行通信)现象 网络知识点 IP地址 192.168.127.170(√) 192.168.…

结构化GPT用例,在CSDN私密社区中死磕@ada 探索SpringBoot

在CSDN私密社区中死磕ada 探索SpringBoot Q: Spring的核心概念是哪些&#xff1f;Q: Spring MVC的核心概念是哪些&#xff1f;Q: SpringBoot的核心概念有哪些&#xff1f;Q: 介绍下SpringBoot AutoConfiguration的机制。Q: SpringBootConfiguration 和 Configuration 的区别是&…

使用esp32+micropython+microdot搭建web(http+websocket)服务器(超详细)第二部分

使用esp32micropythonmicrodot搭建web(httpwebsocket)服务器&#xff08;超详细&#xff09;第二部分 microdot文档速查 什么是Microdot?Microdot是一个可以在micropython中搭建物联网web服务器的框架micropyton文档api速查 Quick reference for the ESP32 实现http服务器 …

基于cycle of curves的Nova证明系统

1. 引言 主要见斯坦福大学Wilson Nguyen、Dan Boneh和微软研究中心Srinath Setty 2023年论文《Revisiting the Nova Proof System on a Cycle of Curves》。 前序博客有&#xff1a; Nova: Recursive Zero-Knowledge Arguments from Folding Schemes学习笔记 在2021年Nova …

Java线程的六种状态(付代码解释)

目录 一.新建状态 (New) 解释 代码 运行结果 ​编辑 二.运行状态(Runnable) 解释 代码 运行结果 三.等待状态&#xff08;Waiting&#xff09; 解释 代码 运行结果 四.阻塞状态&#xff08;Blocked&#xff09; 解释 代码 运行结果 五.计时等待状态&#xff08;…

PCB设计系列分享-开关稳压器接地处理

目录 概要 整体架构流程 技术名词解释 1.DCDC&#xff1a; 2.PGND: 3.AGND: 技术细节 1.认识1 2.认识2 3.综合 小结 概要 提示&#xff1a;这里可以添加技术概要 如何使用带有模拟接地层(AGND)和功率接地层&#xff08;PGND)的开关稳压器? 这是许多开发人员在设计…

启用Windows应急重启功能

博主最近发现了Windows隐藏功能——应急重启&#xff0c;并且这个功能可以追溯到Windows Vista!但是因为大家习惯长按电源键关机所以就鲜为人知。今天博主叫你如何使用应急重启功能。 因为使用功能都无法截图&#xff0c;所以就不展示图片了。 第一步&#xff0c;按住CtrlAltD…