ASP.NET Core怎么使用中间件 Middleware开发与注册方法

ASP.NET Core 中间件是按顺序处理 HTTP 请求和响应的组件,构成“洋葱模型”管道;需在 Program.cs 中用 UseXXX()/MapXXX() 注册,推荐类封装形式(含 InvokeAsync),依赖服务应通过方法参数注入而非构造函数;顺序至关重要,如静态文件须在身份验证前;可用 UseWhen/Map 分支或隔离路径;调试时注意执行时机、短路及响应写入限制。

ASP.NET Core 中间件是处理 HTTP 请求和响应的组件,按顺序构成请求处理管道。开发中间件关键是实现请求委托逻辑,注册则需在 Program.cs(.NET 6+)中通过 UseXXX()MapXXX() 方法挂载。

自定义中间件的两种写法

推荐使用类封装方式,结构清晰、易于测试;也可用内联委托,适合简单逻辑。

  • 类形式中间件(推荐):定义一个类,构造函数接收 RequestDelegate next,实现 InvokeAsync(HttpContext context) 方法。类必须有公共构造函数且不依赖作用域服务(如需 DI,用 InvokeAsync 参数注入)。
  • 内联中间件:直接在 Program.cs 中用 app.Use(async (context, next) => { ... }) 编写,适合调试或一次性逻辑,但不易复用和单元测试。

中间件的注册顺序很重要

中间件执行顺序即注册顺序,靠前的中间件最先接触请求、最后接触响应(类似“洋葱模型”)。错误的顺序会导致功能失效,比如静态文件中间件 UseStaticFiles() 必须在身份验证之前,否则未授权用户也能访问图片等资源。

  • 常用顺序参考:异常处理 → 重定向 → HSTS → HTTPS 强制 → 静态文件 → 身份验证 → 授权 → 路由 → 终结点。
  • UseWhen() 可基于条件分支注册中间件,例如只对 API 路径启用 CORS。
  • Map()MapWhen() 可为特定路径前缀创建子管道,隔离逻辑(如 /health 不走认证)。

在 Program.cs 中注册中间件

.NET 6+ 统一使用 WebApplicationBuilder 构建应用,中间件注册全部在 app 实例上调用方法。

  • 内置中间件如 app.UseRouting()app.UseAuthentication() 直接调用即可。
  • 自定义类中间件用 app.UseMiddleware(),框架自动解析依赖(支持构造函数注入 IServiceScopeFactory 等)。
  • 若中间件依赖作用域服务(如 DbContext),应在 InvokeAsync 方法参数中注入,而非构造函数——避免生命周期冲突。

调试与验证中间件行为

可在中间件中加日志或断点观察执行时机。注意:中间件一旦调用 next(context) 就进入下一个环节,之后代码属于“响应阶段”;若未调用 next,请求就在此终止(如返回 401)。

  • app.Use(async (ctx, next) => { Console.WriteLine("Before"); await next(); Console.WriteLine("After"); }) 快速验证洋葱模型。
  • 检查响应头、状态码、Body 是否被提前写入(调用 context.Response.WriteAsync 后再调 next 会报错)。
  • 结合 DeveloperExceptionPageHttpContext.TraceIdentifier 定位具体请求链路。

基本上就这些。中间件机制本身不复杂,但顺序、生命周期和执行时机容易忽略,写的时候多想想“谁先谁后”“有没有短路”“依赖的服务是不是能拿到”,基本不会踩坑。