You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 6中如何获取Surveyor中间件实例并在控制器中访问

解决控制器无法访问中间件实例的问题

问题根源

  1. 直接通过app.UseMiddleware<Surveyor>()注册中间件时,框架仅创建实例用于请求管道,但未将其注册到依赖注入(DI)容器中,因此控制器无法通过构造函数注入获取该实例。
  2. 即使能注入,当前BlockedAttacks是实例属性,多请求并发修改时会存在线程安全问题,导致统计数据不准确。

最优解决方案:分离状态到独立服务

将攻击统计状态从中间件中抽离为独立服务,既符合单一职责原则,又能安全地在控制器和中间件之间共享数据。

步骤1:创建攻击统计服务

public class AttackStatistics
{
    private long _blockedAttacks;

    // 线程安全地读取统计值
    public long BlockedAttacks => Interlocked.Read(ref _blockedAttacks);

    // 线程安全地递增统计值
    public void IncrementBlockedAttacks()
    {
        Interlocked.Increment(ref _blockedAttacks);
    }
}

步骤2:注册统计服务到DI容器

在Program.cs中添加服务注册:

builder.Services.AddSingleton<AttackStatistics>();

步骤3:修改中间件依赖注入统计服务

更新Surveyor中间件,通过构造函数注入统计服务:

public class Surveyor
{
    private readonly RequestDelegate _next;
    private readonly AttackStatistics _attackStats;

    public Surveyor(RequestDelegate next, AttackStatistics attackStats)
    {
        _next = next;
        _attackStats = attackStats;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (context.Request.Headers.TryGetValue("user-agent", out var userAgent) &&
            !string.IsNullOrWhiteSpace(userAgent))
        {
            if (userAgent.ToString().Contains("eye"))
            {
                _attackStats.IncrementBlockedAttacks();
                context.Response.Redirect("/error");
                return;
            }
        }

        await _next(context);
    }
}

步骤4:在控制器中注入统计服务

public class YourController : Controller
{
    private readonly AttackStatistics _attackStats;

    public YourController(AttackStatistics attackStats)
    {
        _attackStats = attackStats;
    }

    public IActionResult GetBlockedAttacks()
    {
        long count = _attackStats.BlockedAttacks;
        return Ok($"累计拦截攻击次数:{count}");
    }
}

步骤5:保持中间件注册不变

Program.cs中的中间件注册无需修改,依然使用:

app.UseMiddleware<Surveyor>();

为什么不推荐直接注入中间件?

直接将中间件注册到DI容器会遇到RequestDelegate无法提供的问题(该类型属于请求管道的一部分,不能直接注册到DI),同时中间件承担状态管理职责会违反单一原则,不利于后续维护和扩展。

内容的提问来源于stack exchange,提问作者Epic Gamer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:35:42