理解 .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 请求处理的基础结构,掌握中间件可以帮助你:

  • 更好地理解框架内部机制
  • 编写可维护的横切逻辑(监控、日志、权限等)
  • 构建复杂的请求管理系统
相关推荐
止语Lab2 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活2 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困2 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn2 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530142 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908402 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金2 小时前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端
人间凡尔赛2 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
IT_陈寒3 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境3 小时前
提升 Python 代码健壮性的方法大盘点
后端·python