当前位置:

首页 > 编程开发 > C#怎么创建中间件管道_C# ASP.NET Core自定义中间件教程【进阶】

C#怎么创建中间件管道_C# ASP.NET Core自定义中间件教程【进阶】

C#怎么创建中间件管道_C# ASP.NET Core自定义中间件教程【进阶】 说到中间件管道,新手常有个误解,以为它是“创建”出来的一个独立对象。其实不然,管道更像是一条由你亲手组装的流水线,通过 app.Use()、app.UseMiddleware() 和 app.Map() 这些方法,按注册

本文目录

    C#怎么创建中间件管道_C# ASP.NET Core自定义中间件教程【进阶】

    C#怎么创建中间件管道_C# ASP.NET Core自定义中间件教程【进阶】

    说到中间件管道,新手常有个误解,以为它是“创建”出来的一个独立对象。其实不然,管道更像是一条由你亲手组装的流水线,通过 app.Use()、app.UseMiddleware() 和 app.Map() 这些方法,按注册顺序拼接成一条链式的委托流。这里有个关键点:顺序错了、漏了 await next()、或者在不该停下的地方提前返回,管道就会“静默”断裂——系统通常不会报错,但后续所有逻辑都失效了,调试起来相当棘手。

    中间件注册顺序决定执行逻辑,不是可选项

    ASP.NET Core 框架本身可不会帮你检查注册顺序是否合理,它只会忠实地、机械地按照你写的代码顺序来执行。这就意味着,顺序本身就是逻辑的一部分。来看几个典型的顺序陷阱:

    • 身份验证 (app.UseAuthentication()) 必须放在授权 (app.UseAuthorization()) 之前。否则,当授权中间件检查 User.Identity.IsAuthenticated 时,它拿到的还是 false,授权自然会直接失败。
    • 异常处理中间件 (app.UseExceptionHandler()) 需要放在所有可能抛出异常的中间件之前,比如自定义日志中间件或者JWT验证中间件。放晚了,异常就“溜”过去了,根本捕获不到。
    • 静态文件中间件 (app.UseStaticFiles()) 如果放得太靠后,请求可能先被MVC或API中间件拦截并处理了,文件压根没有机会被查找到。

    函数式中间件 vs 类式中间件:什么时候该用哪个

    选择哪种写法,不是看哪个“更高级”,而是取决于实际场景。函数式写法胜在简洁直观,适合那些一次性、无外部依赖、逻辑简单的轻量级任务。而类式写法则能无缝接入依赖注入容器,享受构造器注入和生命周期管理,适合更复杂、有状态的场景。

    • 函数式:像这样 app.Use(async (context, next) => { await context.Response.WriteAsync("hi"); await next(); });。优点一目了然:没有状态管理,不依赖外部服务,调试时所有逻辑尽收眼底。
    • 类式:必须遵循固定模式。构造函数需要接收一个 RequestDelegate 类型的 next 参数,并且必须包含一个名为 InvokeAsync 的公共方法,否则 UseMiddleware() 扩展方法会找不到入口。
    • 还有一个容易踩的坑:类式中间件必须在服务容器中注册(例如 services.AddTransient())。如果忘了这一步,UseMiddleware 在尝试解析依赖时会直接抛出 InvalidOperationException。

    为什么 await next() 漏了就“没反应”

    中间件默认是不会自动调用下一个组件的。漏掉 await next(),就等于你在这条流水线上按下了停止键,后续所有中间件(包括最终的终结点)都不会被执行。更麻烦的是,HTTP响应可能已经部分写出,导致客户端要么一直卡住等待,要么收到一个不完整的响应体。

    • 典型错误:写成 next();(漏了 await)。代码能编译通过,但因为 next 返回的是 Task,不等待它完成就等同于跳过了后续调用,效果和主动短路一样。
    • 调试小技巧:在中间件的开头和结尾分别加上日志输出,比如 Console.WriteLine($"[{nameof(CustomMiddleware)}] enter") 和 Console.WriteLine($"[{nameof(CustomMiddleware)}] exit")。运行时观察日志,如果只看到“enter”而没有对应的“exit”,那基本可以断定是 await next() 被跳过了、中间有未捕获的异常,或者代码提前 return 了。

    Map 分支管道里,next 的含义变了

    当你使用 app.Map("/api", branch => { ... }) 创建分支时,事情变得有点不一样。这里的 branch 参数是一个独立的 IApplicationBuilder,你在它内部通过 Use 注册的中间件,构成的是一个全新的子管道。此时,子管道里的 next 指向的是这个分支内的下一个中间件,而不是主管道里排在 Map 后面的那些。

    • 在分支内部调用 next(),请求不会神奇地回到主管道继续执行。主管道的执行在进入 Map 匹配成功后就已经暂停了。
    • 如果分支管道末尾没有用 Run() 明确终止,或者没有匹配到任何终结点,请求就会“掉出”分支。但请注意,它不会自动回到主管道,而是直接结束,通常返回一个404状态码。
    • 那么,有没有办法让分支处理完再回到主流程?答案是:不行。Map 的设计就是隔离的。如果真有跨分支和主管道的复用逻辑,正确的做法是将其抽离成共享的服务,而不是指望管道能自动穿透。

    话说回来,真正考验开发者的,往往不是中间件本身的编写,而是两个关键判断:「这个业务逻辑到底该不该放在中间件里?」以及「如果该放,它应该插在管道的哪个位置?」很多看似“通用”的需求,比如统一的响应格式包装,其实放在控制器基类、Action过滤器或者像 IApiResponseFormatter 这类更贴近业务层的扩展点上会更合适。中间件位于请求处理管道的底层,一旦写错或设计不当,影响的是流经它的每一个请求,排查起来反而更费周章。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 C#
    相关文章 更多
    winforms教程自学入门与基础开发步骤详解
    winforms教程自学入门与基础开发步骤详解

    本教程详细讲解如何使用Visual Studio创建WinForms项目,通过添加按钮和标签控件并编写点击事件代码,实现一个基础的计数器功能,适合C#初学者快速上手Windows窗体应用开发。

    圆通速递查单号官网
    圆通速递查单号官网

    圆通速递查单号官网在哪里? 不少朋友都在寻找圆通快递的官方物流查询入口。别急,这就为你揭晓答案,并带你详细了解它的核心功能与服务。 圆通速递的官方网站地址是:https://www.yto.net.cn/。记住这个地址,所有官方服务都从这里开始。 官网核心功能 来到官网,你会发现它的运单查询服务是全

    在小说搜搜找不到想看的小说怎么办?小说搜搜换源功能使用详解【必学】
    在小说搜搜找不到想看的小说怎么办?小说搜搜换源功能使用详解【必学】

    小说搜搜搜索不到结果?五种实用解决方法帮你搞定 在小说搜搜里搜不到想看的书?这事儿其实挺常见。问题多半出在书源上——要么是默认的书源还没来得及收录,要么是原先的源数据失效了,更新没跟上。别急,下面这五条解决路径,基本能覆盖绝大多数情况,操作起来也不复杂。 一、通过阅读页调出换源入口手动切换 这个方法

    来看小说网最新章节免费阅读网
    来看小说网最新章节免费阅读网

    来看小说网最新章节免费阅读网-来看小说网全网小说同步更新入口 不少资深书友都在问,来看小说网的全网小说同步更新入口究竟在哪?别急,答案就在这里。接下来,就为大家详细揭开这个平台的神秘面纱,看看它究竟提供了怎样的阅读体验。 来看小说网的官方入口是:https://www.kanxiaoshuo.net

    谈编程与编程语言
    谈编程与编程语言

    编程的本质是创造性的严谨翻译,通过for、if和函数调用实现重复计算任务。语言发展让集成度提高,门槛降低但竞争加剧。程序员需培养整体架构能力,抓住思想精髓而非追逐新技术,方能长远发展。

    什么是面向接口编程、面向过程编程、面向对象编程?
    什么是面向接口编程、面向过程编程、面向对象编程?

    面向接口编程通过接口解耦,降低耦合度并提升可扩展性和维护性,是面向对象思想的精髓。面向过程编程将问题拆解为步骤,用函数依次执行。面向对象编程将事物抽象为对象,封装属性和方法,通过对象协作解决问题。

    我对编程的一些感悟
    我对编程的一些感悟

    编程这件事,说到底是门手艺活,但又不全是手艺。把代码写出来容易,把代码写好、写出境界,那就得看功夫了。今天聊几个核心判断,算是多年敲键盘的一点沉淀。 一、语言是功夫,思路是内功 编程语言五花八门,就像武林高手会的功夫一样,但想成为顶尖高手,内功必须深厚。内功到了,学新功夫就是分分钟的事。看过《倚天屠

    c#如何使用abstract类_c#abstract类看这一篇就够了_保姆级教程
    c#如何使用abstract类_c#abstract类看这一篇就够了_保姆级教程

    abstract类不能被直接实例化,子类必须用override实现其所有抽象方法。抽象类可实现接口,并以抽象方法转发接口成员。抽象类不能与sealed共用,其抽象方法默认隐式virtual且无方法体。可包含字段、属性等非抽象成员。

    c#如何删除文件_c#删除文件的正确用法与注意事项
    c#如何删除文件_c#删除文件的正确用法与注意事项

    C#删除文件前应先判断存在性以防异常,注意权限不足和文件被占用。File.Delete与FileInfo.Delete功能相同,后者适合多次操作。无异步删除方法,推荐后台执行或限流以避免阻塞。

    c#如何使用EmguCV_c#EmguCV的最佳实践与常见坑点
    c#如何使用EmguCV_c#EmguCV的最佳实践与常见坑点

    在EmguCV中,进行Bitmap转Image时,需先转为24位无Alpha格式,以避免颜色错乱问题;Image转Bitmap时,建议使用Mat或ImageBox控件,以有效减少内存拷贝;跨线程处理时,应使用Mat.Clone()进行深拷贝,以确保数据安全;DLL加载失败时,需设置x64平台目标,并确保native库在输出目录中。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。