ASP.NET Core中间件是按顺序处理HTTP请求响应的组件,可写为lambda委托或封装成带依赖注入的类,注册顺序决定执行逻辑,需注意短路、前置/后置时机及Options配置。

ASP.NET Core 中间件就是处理 HTTP 请求和响应的组件,按顺序组成管道。自定义中间件本质是一个接收 RequestDelegate(下一个中间件)并返回 Task 的委托,或封装成类更清晰、可复用。
写一个基础函数式中间件
最简方式是直接在 Program.cs 中用 lambda 编写:
app.Use(async (context, next) =>
{
// 在下一个中间件执行前做的事(前置逻辑)
Console.WriteLine("请求开始");
await next(); // 调用管道中的下一个中间件
// 在下一个中间件执行后做的事(后置逻辑)
Console.WriteLine("请求结束");
});
注意:必须调用 next() 才能让请求继续向下走;不调用就“短路”了(比如做身份验证失败直接返回 401)。
封装成可重用的中间件类
推荐做法,利于测试、配置和复用。例如写一个记录请求耗时的中间件:
public class TimingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public TimingMiddleware(RequestDelegate next, ILogger logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var watch = Stopwatch.StartNew();
await _next(context);
watch.Stop();
_logger.LogInformation("请求 {Path} 耗时 {ElapsedMs}ms",
context.Request.Path, watch.ElapsedMilliseconds);
}
}
然后在 Program.cs 中注册并使用:
app.UseMiddleware();
如果需要传参(如开关、阈值),可加一个 Options 类配合构造函数注入。
中间件的执行顺序很关键
中间件按 UseXXX 的调用顺序加入管道,越靠前的越先执行「前置」,越靠后的越先执行「后置」。常见顺序建议:
-
异常处理(
UseExceptionHandler)放最前,捕获后续所有异常 -
静态文件(
UseStaticFiles)通常较早,避免走完整管道 -
认证/授权(
UseAuthentication、UseAuthorization)放在路由之前 -
终结点路由(
UseEndpoints或MapControllers)放在最后,真正分发请求
顺序错了可能导致功能失效(比如把认证放路由后面,就根本不会校验)。
带参数的中间件写法(Options 模式)
比如想让 TimingMiddleware 只对特定路径计时,或设置慢请求告警阈值:
public class TimingOptions
{
public string? PathPrefix { get; set; } = "/";
public long WarnThresholdMs { get; set; } = 500;
}
修改中间件构造函数注入 IOptions,并在 InvokeAsync 中判断路径和耗时:
if (!context.Request.Path.StartsWithSegments(options.Value.PathPrefix))
return await _next(context);
注册时可配置:
builder.Services.Configure(opt => { opt.PathPrefix = "/api/"; opt.WarnThresholdMs = 200; }); app.UseMiddleware ();
基本上就这些。核心就三点:理解委托链、掌握类封装写法、盯紧注册顺序。不复杂但容易忽略细节。










