IE盒子

搜索
查看: 135|回复: 1

ASP.NET 6 中间件

[复制链接]

3

主题

8

帖子

17

积分

新手上路

Rank: 1

积分
17
发表于 2023-1-16 13:09:53 | 显示全部楼层 |阅读模式


这是一个关于 .NET 6 中间件的系列文章。
在这个系列中,我们将了解到什么是中间件,它能够做什么,以及我们为什么要使用它,并演示几种不同类型的中间件的实现。
之后,我们会进一步了解中间件所在的管道,以及如何创建它。
最后,我们再展示两种根据不同条件在管道中执行中间件的方法,以便更细粒度地控制应用程序的操作。
中间件基础

一般情况下,任何使用 HTTP 进行的交互都由请求(通常来自浏览器)和响应组成。浏览器或其他请求者通过提交请求,并等待请求目标(Web 服务器)返回响应。
中间件则位于请求者和目标之间,因此它可以直接修改响应的内容,还可以使用请求中的数据做出其它响应行为。
就像这张图:



http://ASP.NET 6 实现了一个由一系列中间件组成的管道。请求沿着这个管道向下过滤,直到它到达一个中间件创建响应为止。然后,响应再逆向通过管道进行过滤,直到它到达请求者。
每个中间件组件由一个请求委托组成,这是 .NET 中的一种特定对象,它可以将执行控制传递给下一个对象。每个请求委托都可以选择是否将请求传递给管道中的下一个委托。
也就是说,根据请求委托处理的结果,中间件也有可能不会选择将执行控制权交给下一个委托。
中间件的用途

中间件的一个常见的场景,就是日志记录。中间件可以轻松地将请求(包括URL和路由)记录到日志系统中,以便以后进行分析。
中间件也是进行授权和身份验证、诊断、异常记录和处理的好地方。
简而言之,中间件可以用于那些不是特定于业务领域的逻辑,以及需要在每个请求或大多数请求中发生的操作。
Program.cs 示例

这是 Visual Studio 创建 http://ASP.NET 6 Web 应用程序时,默认生成的 Program.cs 文件,并且进行了简单的修改:
var builder = WebApplication.CreateBuilder(args);// 添加服务builder.Services.AddRazorPages(); var app = builder.Build();// 配置 HTTP 请求管道if (!app.Environment.IsDevelopment()){    app.UseExceptionHandler("/Error");    app.UseHsts();}// 将各种中间件添加到应用程序管道中app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.MapRazorPages();//最后运行应用app.Run();这个文件创建了 http://ASP.NET 6 Web 应用程序处理请求的管道。它还使用 .NET 6 提供的特殊方法向管道中添加了一组「默认」中间件。
例如UseStaticFiles(),它允许应用程序返回静态文件,如 .js 和. css;以及UseRouting() ,它添加了.NET Routing 来处理 URL 到服务器端点的路由。
此外,http://ASP.NET 6 应用程序可以使用很多默认提供的这种“内置”中间件。具体可以查看官方文档。
一个简单的自定义中间件

让我们创建一个超级简单的中间件,它只做一件事:返回 “Hello Dear Readers!” 作为响应。
在 Program.cs 中,我们使用 Run() 方法添加了一个新的中间件,如下所示:
app.Run(async context =>{    await context.Response.WriteAsync("Hello Dear Readers!");});app.UseRouting();app.UseAuthorization();app.MapRazorPages();app.Run();当我们运行这个应用程序时,我们会看到这个非常简单的输出:



现在,我们已经在 http://ASP.NET 6 中实现了自定义的中间件,然而,还有一个问题,我们之后就会看到。
Run()、Use() 和 Map()

当我们查看 Program.cs 文件时,通常可以通过查看添加到管道的方法,来确定应用程序的哪些部分被认为是中间件。
最常见的方法是 Run()、Use() 和Map()。
Run()

Run() 方法会在管道的终点调用一个中间件。因此,该中间件将始终是一个终结点,也就是,响应返回之前执行的最后一个中间件。
例如前面示例的代码:
app.Run(async context =>        {            await context.Response.WriteAsync("Hello Dear Readers!");        });// 下面的代码都不会被执行app.UseRouting();app.UseAuthorization();app.MapRazorPages();app.Run();因为调用了 Run() ,所以在该调用之后不会执行任何写入的内容。
Use()

Use()方法在管道中放置一个中间件,并允许该中间件将控制权传递给管道中的下一项。
app.Use(async (context, next) =>{    //做一些不修改响应的操作    await next.Invoke();    //执行日志记录或不写入响应的操作});注意next参数,该参数就是前面提到的请求委托。它表示管道中的下一个中间件,不管它是什么。
通过等待next.Invoke(),我们允许请求继续传递到下一个中间件。
另外,请注意,除非管道在这里停止处理,否则在这种中间件中最好不要修改响应。修改已经生成的响应可能会导致响应损坏。
大多数时候我们都会使用Use()而不是Run()来添加中间件到管道中。
Map()

Map()方法允许我们创建具有分支的管道,我们可以使用它根据请求路径有条件地调用中间件。
app.Map("/branch1", HandleBranchOne);app.Map("/branch2", HandleBranchTwo);app.Run();static void HandleBranchOne(IApplicationBuilder app){    app.Run(async context =>    {        await context.Response.WriteAsync("You're on Branch 1!");    });}static void HandleBranchTwo(IApplicationBuilder app){    app.Run(async context =>    {        await context.Response.WriteAsync("You're on Branch 2!");    });}Map()方法比较特殊,我们将在后面的文章中详细讨论。
总结

中间件是组成管道的代码模块或类。该管道处理传入的请求和传出的响应。
在 Program.cs 文件中,我们可以按照特定的顺序放置中间件,然后它将按照该顺序执行请求,并以相反的顺序执行响应。
http://ASP.NET 6 包含了很多内置的中间件,其中一些几乎可以在所有的 Web 应用中使用。
向应用管道中添加中间件的一种方法是使用Run()、Use()和Map()方法。然而,这可能不是最常见的方式,我们会在下一篇文章中再详细说明。
技术群:添加小编微信并备注进群

小编微信:mm1552923
公众号:dotNet编程大全
回复

使用道具 举报

1

主题

7

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2025-6-8 01:26:41 | 显示全部楼层
一直在看
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表