ASP.NET Core中间件怎么编写 自定义Middleware管道方法

来源:这里教程网 时间:2026-02-21 17:35:46 作者:

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<TimingMiddleware> _logger;
    public TimingMiddleware(RequestDelegate next, ILogger<TimingMiddleware> 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<TimingMiddleware>();

如果需要传参(如开关、阈值),可加一个 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<timingoptions></timingoptions>
,并在
InvokeAsync
中判断路径和耗时:

if (!context.Request.Path.StartsWithSegments(options.Value.PathPrefix))
    return await _next(context);

注册时可配置:

builder.Services.Configure<TimingOptions>(opt =>
{
    opt.PathPrefix = "/api/";
    opt.WarnThresholdMs = 200;
});
app.UseMiddleware<TimingMiddleware>();

基本上就这些。核心就三点:理解委托链、掌握类封装写法、盯紧注册顺序。不复杂但容易忽略细节。

相关推荐