理解 .NET 中的中间件(Middleware)

理解 .NET 中的中间件(Middleware):请求管道的核心机制

ASP.NET Core 中,中间件(Middleware)是整个 Web 应用的核心机制之一。所有 HTTP 请求都会依次通过一系列中间件处理,这些中间件共同组成了所谓的 请求管道(Request Pipeline) 。理解中间件不仅有助于掌握 ASP.NET Core 的工作原理,更能帮助你构建结构清晰、可扩展且易维护的 Web 应用。

本文将从中间件的概念、执行流程、如何编写自定义中间件以及开发中的最佳实践等方面进行介绍。


一、中间件是什么?

中间件是用于处理 HTTP 请求和响应的组件。每个中间件在管道中有两个职责:

  1. 处理当前请求
  2. 将请求传递给管道中的下一个中间件(可选)

典型逻辑可以概括为:

css 复制代码
Request → [Middleware1] → [Middleware2] → ... → Endpoint

中间件既可以选择"继续往下传",也可以"短路"整个请求。

例如:

  • 认证中间件可能会拒绝未授权请求,直接返回 401。
  • 静态文件中间件会直接返回文件内容,不继续传递到 MVC 层。

二、中间件的注册方式

.NET 6+ 的程序入口里,你常看到这样的代码:

ini 复制代码
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app.Run();

UseXXX() 即是在管道中注册中间件。

通常中间件的处理顺序非常重要,例如:

  • UseRouting() 必须在 UseEndpoints() 前。
  • UseAuthorization() 要在 UseAuthentication() 后。

如果顺序错误,可能导致路由不生效或认证失败。


三、编写一个自定义中间件

自定义中间件通常有两种方式:类方式与委托方式。

方式一:通过类编写中间件

1. 编写中间件类
csharp 复制代码
public class RequestLogMiddleware
{
    private readonly RequestDelegate _next;

    public RequestLogMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        Console.WriteLine($"[Request] {context.Request.Method} {context.Request.Path}");

        await _next(context); // 继续传递给下一个中间件

        Console.WriteLine($"[Response] {context.Response.StatusCode}");
    }
}
2. 注册中间件
ini 复制代码
app.UseMiddleware<RequestLogMiddleware>();

方式二:使用 inline delegate 简写(更轻量)

python 复制代码
app.Use(async (context, next) =>
{
    Console.WriteLine("Before");
    await next(context);
    Console.WriteLine("After");
});

四、中间件执行流程示例

假设我们有三层中间件:

python 复制代码
app.Use(async (context, next) =>
{
    Console.WriteLine("1 - Before");
    await next();
    Console.WriteLine("1 - After");
});

app.Use(async (context, next) =>
{
    Console.WriteLine("2 - Before");
    await next();
    Console.WriteLine("2 - After");
});

app.Map("/hello", () => "Hello");

执行顺序会是:

复制代码
1 - Before
2 - Before
(进入 endpoint)
2 - After
1 - After

这体现了 洋葱模型(Onion Model) 的特性。


五、中间件的典型应用场景

中间件的应用非常广泛,几乎所有现代 Web 框架都会使用类似的机制。ASP.NET Core 中常见的中间件包括:

  • 异常捕获(UseExceptionHandler)
  • 静态文件处理(UseStaticFiles)
  • 跨域 CORS(UseCors)
  • 身份认证 Auth(UseAuthentication)
  • 压缩响应(UseResponseCompression)
  • 日志记录与监控(自定义)

例如:要捕获全局异常,可以这样:

arduino 复制代码
app.UseExceptionHandler("/error");

或者写一个自定义全局异常中间件。


六、开发中常见问题与最佳实践

1. 中间件顺序非常关键

  • 错误顺序会导致功能失效
  • 官方文档明确列出了推荐顺序,建议参考

2. 避免在中间件中做耗时操作

慢中间件会拖垮整个链路。

3. 如果中止管道,要确保正确设置响应(StatusCode、Header)

例如,权限不足时返回:

ini 复制代码
context.Response.StatusCode = StatusCodes.Status403Forbidden;
return;

4. 避免在中间件中直接访问大量业务逻辑

业务逻辑应该在 Service 层。


结语

中间件是 ASP.NET Core 请求处理的基础结构,掌握中间件可以帮助你:

  • 更好地理解框架内部机制
  • 编写可维护的横切逻辑(监控、日志、权限等)
  • 构建复杂的请求管理系统
相关推荐
程序员爱钓鱼40 分钟前
Go操作Excel实战详解:github.com/xuri/excelize/v2
前端·后端·go
oak隔壁找我8 小时前
MySQL中 SHOW FULL PROCESSLIST` 输出中 `State` 列的所有可能值
后端
上进小菜猪9 小时前
基于 YOLOv8 的面向文档智能处理的表格区域检测系统 [目标检测完整源码]
后端
oak隔壁找我9 小时前
JVM常用调优参数
java·后端
IT_陈寒13 小时前
React状态管理终极对决:Redux vs Context API谁更胜一筹?
前端·人工智能·后端
晨星shine13 小时前
GC、Dispose、Unmanaged Resource 和 Managed Resource
后端·c#
蝎子莱莱爱打怪13 小时前
OpenClaw 从零配置指南:接入飞书 + 常用命令 + 原理图解
java·后端·ai编程
倚栏听风雨14 小时前
【ES避坑指南】明明存的是 "CodingAddress",为什么 term 查询死活查不到?彻底搞懂 text 和 keyword
后端
程序员爱钓鱼14 小时前
Go 操作 Windows COM 自动化实战:深入解析 go-ole
后端·go·排序算法
回家路上绕了弯14 小时前
深入解析Agent Subagent架构:原理、协同逻辑与实战落地指南
分布式·后端