2016年ASP.NET Core发布时,微软重构了整个HTTP处理管道。8年后,仍有团队在控制器里写重复代码——日志、鉴权、异常处理,像在机场安检口手工翻包。

中间件(Middleware)就是那条安检流水线。每个HTTP请求像旅客,依次经过证件查验→行李扫描→人身检查,最后登机(抵达控制器)。返程时原路折返,取行李、过闸机。每个检查点都是一段可插拔的代码

为什么控制器不该干这些脏活

为什么控制器不该干这些脏活

想象你在每个登机口重复建安检通道。某航空公司有200个API端点,意味着200份重复的错误处理、200份重复的日志格式、200份重复的鉴权逻辑。

中间件把"横切关注点"(Cross-Cutting Concerns)抽离成独立组件。日志写一次,全站生效;异常捕获写一次,所有API统一返回格式。控制器只负责业务,像飞行员只开飞机,不查护照。

微软文档里的比喻很直白:管道是洋葱结构。请求从外向内穿透每层,响应从内向外渗出。每层都能决定是否"短路"——比如鉴权失败直接返回401,不让请求继续深入。

写一段能用的中间件需要几步

写一段能用的中间件需要几步

三步。定义类→实现Invoke/InvokeAsync→在Program.cs注册顺序。

核心是一个异步方法,接收HttpContext和下一个中间件的委托。你可以在处理请求前执行代码(请求阶段),调用_next(context)把请求踢给下游,等返回后再执行代码(响应阶段)。

顺序是陷阱。注册时先写的先执行请求阶段、后执行响应阶段——像叠罗汉,最底层的人最后站起来。日志中间件通常放最外层,确保能记录响应状态码;异常处理要更外层,才能捕获内层抛出的错误。

一个细节:异步方法必须await _next(context),否则响应阶段代码不会执行。很多新手在这里栽过,请求进去了,日志没记上。

什么场景值得专门写中间件

什么场景值得专门写中间件

不是每个功能都适合。微软官方中间件已经覆盖了静态文件、路由、认证、会话、响应压缩等80%需求。自定义中间件的价值在"业务专属横切逻辑":比如给所有API响应注入请求追踪ID,让日志和分布式追踪串联;比如统一包装业务异常,把堆栈藏进内部系统、对外只暴露友好错误码。

某电商团队曾把"接口耗时监控"写进基类控制器,新增API时忘了继承,监控就漏了。改成中间件后,漏网率为零——管道不挑控制器,流经必触发。

但别滥用。业务逻辑放中间件,就像让安检员决定你坐头等舱还是经济舱。管道应该薄、快、无副作用。需要查数据库的决策,留在控制器里。

最后留个细节:ASP.NET Core 8新增了IExceptionHandler接口,专门接管异常处理中间件的脏活。老式的中间件写异常处理还能跑,但新项目的异常中间件,你打算继续手写还是迁移?