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

  • 更好地理解框架内部机制
  • 编写可维护的横切逻辑(监控、日志、权限等)
  • 构建复杂的请求管理系统
相关推荐
小马爱打代码4 小时前
SpringBoot:封装 starter
java·spring boot·后端
STARSpace88884 小时前
SpringBoot 整合个推推送
java·spring boot·后端·消息推送·个推
Marktowin5 小时前
玩转 ZooKeeper
后端
蓝眸少年CY6 小时前
(第十二篇)spring cloud之Stream消息驱动
后端·spring·spring cloud
码界奇点6 小时前
基于SpringBoot+Vue的前后端分离外卖点单系统设计与实现
vue.js·spring boot·后端·spring·毕业设计·源代码管理
lindd9119116 小时前
4G模块应用,内网穿透,前端网页的制作第七讲(智能头盔数据上传至网页端)
前端·后端·零基础·rt-thread·实时操作系统·项目复刻
Loo国昌7 小时前
【LangChain1.0】第八阶段:文档处理工程(LangChain篇)
人工智能·后端·算法·语言模型·架构·langchain
vx_bisheyuange7 小时前
基于SpringBoot的海鲜市场系统
java·spring boot·后端·毕业设计
李慕婉学姐8 小时前
【开题答辩过程】以《基于Spring Boot和大数据的医院挂号系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
大数据·spring boot·后端
源代码•宸9 小时前
Leetcode—3. 无重复字符的最长子串【中等】
经验分享·后端·算法·leetcode·面试·golang·string