当前位置: 首页 > news >正文

C# Web开发教程(八)中间件

中间件

- 广义: ASP.NETCore中的中间件指ASP.NETCore中的一个组件。- 组成部分: 中间件由前逻辑、next、后逻辑3部分组成,前逻辑为第一段要执行的逻辑代码、next为指向下一个中间件的调用、   后逻辑为从下一个中间件执行返回所执行的逻辑代码。每个HTTP请求都要经历一系列中间件的处理,每个中间件对于请求进行特   定的处理后,再转到下一个中间件,最终的业务逻辑代码执行完成后,响应的内容也会按照处理的相反顺序进行处理,然后形成   HTTP响应报文返回给客户端。- 中间件组成一个管道,整个ASP.NETCore的执行过程就是HTTP请求和响应按照中间件组装的顺序在中间件之间流转的过程。开发人员可以对组成管道的中间件按照需要进行自由组合。
  • 中间件的三个概念: Map,Use,Run
- Map用来定义一个管道可以处理哪些请求
- Use和Run用来定义管道,一个管道由若干个Use和一个Run组成,每个Use引入一个中间件,而Run是用来执行最终的核心应用逻辑。
  • 我们创建一个空asp.net项目,从一无所有开始搭建中间件
// Program.cs(很简单的代码,跑起来只有一个Hello World!)var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();app.MapGet("/", () => "Hello World!");app.Run();- 运行: https://localhost:7118/- 我们可以小改一下,返回简单字符
......
app.MapGet("/", () => "Hello World!");
app.MapGet("/test", () => "你若xxxx");
......
  • 来一个简单示例
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();app.MapGet("/", () => "Hello World!");
//app.MapGet("/test", () => "你若xxxx");app.Map("/test", async (pipeBuilder) =>
{pipeBuilder.Use(async (context, next) =>{context.Response.ContentType = "text/html";await context.Response.WriteAsync("1 start<br/>");await next.Invoke();await context.Response.WriteAsync("1 end<br/>");});pipeBuilder.Use(async (context, next) =>{await context.Response.WriteAsync("2 start<br/>");await next.Invoke();await context.Response.WriteAsync("2 end<br/>");});pipeBuilder.Use(async (context, next) =>{await context.Response.WriteAsync("3 start<br/>");await next.Invoke();await context.Response.WriteAsync("3 end<br/>");});pipeBuilder.Run(async context =>{await context.Response.WriteAsync("Run<br/>");});});app.Run();

自定义中间件管道(重点)

app.Map("/test", async (pipeBuilder) =>
{// 创建自定义的中间件管道
});

中间件管道详细解析

管道执行顺序:

请求 → 中间件1 → 中间件2 → 中间件3 → Run终端 → 中间件3 → 中间件2 → 中间件1 → 响应

三个中间件的执行流程:

pipeBuilder.Use(async (context, next) =>
{context.Response.ContentType = "text/html";await context.Response.WriteAsync("1 start<br/>");  // 1. 进入时执行await next.Invoke();                                // 2. 调用下一个中间件await context.Response.WriteAsync("1 end<br/>");    // 7. 返回时执行
});pipeBuilder.Use(async (context, next) =>
{await context.Response.WriteAsync("2 start<br/>");  // 3. 进入时执行await next.Invoke();                                // 4. 调用下一个中间件await context.Response.WriteAsync("2 end<br/>");    // 6. 返回时执行
});pipeBuilder.Use(async (context, next) =>
{await context.Response.WriteAsync("3 start<br/>");  // 5. 进入时执行await next.Invoke();                                // 调用Run(没有下一个中间件)await context.Response.WriteAsync("3 end<br/>");    
});

终端中间件

pipeBuilder.Run(async context =>
{await context.Response.WriteAsync("Run<br/>");      // 5.5 执行并终止管道
});

实际输出结果

访问 /test 路径时,浏览器会显示:

1 start
2 start
3 start
Run
3 end
2 end
1 end

关键概念说明

  1. Use() - 添加中间件,可以调用下一个中间件
  2. Run() - 终端中间件,终止管道传递
  3. next.Invoke() - 调用管道中的下一个中间件
  4. 洋葱模型 - 中间件的执行顺序:进入时正序,返回时逆序

这个示例很好地展示了ASP.NET Core中间件管道的执行原理和"洋葱模型"的工作方式。

  • 注意事项: 此时若执行Run()以后,依然运行pipeBuilder.Use是不会生效了

    • 通俗理解,相当于已经return了,那么return后面再写语句,肯定是不会执行的
    ......pipeBuilder.Run(async context =>{await context.Response.WriteAsync("Run<br/>");});// 不会执行pipeBuilder.Use(async (context, next) =>{await context.Response.WriteAsync("4 start<br/>");await next.Invoke();await context.Response.WriteAsync("4 end<br/>");});
    

简单的自定义中间件

  • 如果中间件的代码比较复杂,或者我们需要重复使用一个中间件的话,我们最好把中间件的代码放到一个单独的“中间件类”中。
- 中间件类是一个普通的.NET类,它不需要继承任何父类或者实现任何接口,但是这个类需要有一个构造方法,构造方法至少要有   一个RequestDelegate类型的参数,这个参数用来指向下一个中间件。这个类还需要定义一个名字为Invoke或InvokeAsync的   方法,方法至少有一个HttpContext类型的参数,方法的返回值必须是Task类型。中间件类的构造方法和lnvoke(或           lnvokeAsync)方法还可以定义其他参数,其他参数的值会通过依赖注入自动赋值。
// Test1Middleware.csnamespace WebApplicationAboutMiddleWare
{public class Test1Middleware{private readonly RequestDelegate next;public Test1Middleware(RequestDelegate next){this.next = next;}public async Task InvokeAsync(HttpContext context){await context.Response.WriteAsync("I'm in Test1Middleware: start...<br/>");await next.Invoke(context);await context.Response.WriteAsync("I'm in Test1Middleware: end...<br/>");}}
}// Program.cs......
app.Map("/test", async (pipeBuilder) =>
{pipeBuilder.Use(async (context, next) =>{context.Response.ContentType = "text/html";await context.Response.WriteAsync("1 start<br/>");await next.Invoke();await context.Response.WriteAsync("1 end<br/>");});pipeBuilder.Use(async (context, next) =>{await context.Response.WriteAsync("2 start<br/>");await next.Invoke();await context.Response.WriteAsync("2 end<br/>");});pipeBuilder.Use(async (context, next) =>{await context.Response.WriteAsync("3 start<br/>");await next.Invoke();await context.Response.WriteAsync("3 end<br/>");});// 应用pipeBuilder.UseMiddleware<Test1Middleware>();pipeBuilder.Run(async context =>{await context.Response.WriteAsync("Run<br/>");});});app.Run();- 测试: https://localhost:7118/test,返回结果1 start
2 start
3 start
I'm in Test1Middleware: start...
Run
I'm in Test1Middleware: end...
3 end
2 end
1 end
http://www.hskmm.com/?act=detail&tid=37217

相关文章:

  • 2025年10月朝阳门美食酒店推荐榜:福宫领衔五强对比评测
  • cookie
  • 自动化组件库AdvLibSuite.CCUnified发布
  • WPF开发库推荐
  • HTML详解
  • 自我成长 - 木易
  • DeepSeek OCR:10倍文档压缩,97%准确率,让你的 LLM 读得更快、更省
  • 10.23 Session、Cookie、Token的核心区别;Cookie和缓存(Cache)的区别
  • MyEMS 核心功能拆解:数据采集、能耗分析、智能调控如何落地?
  • 有了 MCP,为啥 Claude 还要推出 Skills?一文带你搞懂它到底强在哪? MCP 有啥区别、该怎么用!
  • 批量跑脚本后自定义消息内容发送至钉钉--批量跑脚本
  • 赋能未来测试英才:“测吧”一站式实训平台,为高校软件测试教学按下“加速键”
  • ​FAQ: 如何在 WPF 项目中强制指定统一输出目录并确保 VS 调试正常? - 教程
  • 10 23
  • 2025 年锚固剂生产厂家最新推荐排行榜:锚杆 / 矿用 / 树脂锚固剂实力企业深度解析
  • 2025年10月留香沐浴露推荐:五强口碑榜对比评测
  • 已经设置过 settings.json,但是运行 claude 时,依旧提示 Missing API key Run /login
  • drools 规则引擎在线化配置
  • 2025年10月中国宝宝辅食品牌推荐榜:妈妈口碑对比榜
  • 小白指南(六)——在线安装minio存储系统(Linux版通用)
  • 欧拉图笔记
  • 2025年10月浦东装修公司推荐榜:五强排名深度评测 2025年10月浦东装修公司榜:五强对比与选择指南
  • 2025 年真空泵维修厂家最新推荐榜:覆盖宁波杭州金华绍兴等城市优质厂家,全方位解析核心竞争力助企业精准选型
  • 2025年10月抗老面霜推荐榜:五款口碑单品深度对比评测
  • 2025 年国内挤塑板厂家最新推荐排行榜:聚焦优质企业,助力建筑保温材料精准选购聚苯乙烯/聚乙烯/广东/优质/高密度挤塑板厂家推荐
  • 2025年法兰保护罩厂家推荐排行榜,阀门保温罩,法兰罩,法兰防溅罩,法兰保护套源头厂家专业实力解析
  • 2025年滑石粉厂家推荐排行榜,纳米级滑石粉,工业级滑石粉,黑色滑石粉,高白滑石粉,化妆品级滑石粉,食品级滑石粉,表面改性滑石粉,大片径比滑石粉,低收缩率滑石粉,高填充母粒滑石粉厂家推荐
  • 北京房产纠纷律师服务口碑榜:专业能力与胜诉案例深度评估
  • 2025年10月汽车衡厂家推荐排行榜:重庆赛宁特全维度评测
  • 【高录用、见刊快】2025年教育技术与管理信息系统国际学术会议(ETMIS 2025)