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

.NET 6 添加JWT中间件报错:无法从根提供程序解析AGUSContext

问题分析与解决方案

问题根源

System.InvalidOperationException异常的核心原因是:你从根服务提供者(Root Provider)中尝试解析了一个Scoped生命周期的服务AGUSContext。在.NET中,根服务提供者是单例的,而Scoped服务的生命周期绑定到请求作用域,根容器没有请求上下文,无法创建或管理Scoped服务的生命周期。

你的JWT中间件默认是单例生命周期,若在中间件构造函数中注入Scoped服务,或直接从根容器获取Scoped服务,就会触发这个错误。


具体解决方案

1. 修改JwtMiddleware的服务获取方式

不要在中间件构造函数中注入AGUSContext,而是在InvokeAsync方法中通过当前请求的作用域服务提供者获取:

public async Task InvokeAsync(HttpContext context)
{
    // 创建当前请求的临时作用域,获取Scoped服务
    using var scope = context.RequestServices.CreateScope();
    var dbContext = scope.ServiceProvider.GetRequiredService<AGUSContext>();

    // 后续JWT验证逻辑使用dbContext
    var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
    if (!string.IsNullOrEmpty(token))
    {
        ValidateToken(token, dbContext, context);
    }

    await _next(context);
}

2. 限制中间件构造函数的注入类型

中间件是单例生命周期,构造函数只能注入Singleton服务(比如IConfiguration、单例配置类等),禁止注入Scoped/Transient服务:

// 正确示例:仅注入单例服务
public JwtMiddleware(RequestDelegate next, IConfiguration configuration)
{
    _next = next;
    _configuration = configuration;
}

// 错误示例:禁止构造函数注入Scoped服务
// public JwtMiddleware(RequestDelegate next, AGUSContext dbContext)

3. 确认Program.cs中的服务注册

确保AGUSContext是按Scoped生命周期注册(AddDbContext默认就是Scoped):

builder.Services.AddDbContext<AGUSContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("AGUSConnection")));

4. 修正授权特性中的服务获取(若涉及)

如果自定义授权特性中也用到了AGUSContext,同样要通过请求作用域获取,不能在构造函数注入:

public class CustomAuthorizeAttribute : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        using var scope = context.HttpContext.RequestServices.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<AGUSContext>();
        
        // 授权逻辑...
    }
}

5. 控制器生成Token的代码无需修改

控制器是Scoped生命周期,构造函数直接注入AGUSContext是安全的:

[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase
{
    private readonly AGUSContext _dbContext;
    private readonly IConfiguration _configuration;

    public AuthController(AGUSContext dbContext, IConfiguration configuration)
    {
        _dbContext = dbContext;
        _configuration = configuration;
    }

    [HttpPost("login")]
    public IActionResult GenerateToken(LoginModel model)
    {
        // 使用_dbContext验证用户并生成Token
        // ...
    }
}

关键原理

  • .NET中间件默认是Singleton,只能从构造函数注入Singleton服务;
  • Scoped服务绑定到请求上下文,必须通过HttpContext.RequestServices创建临时作用域获取;
  • 使用CreateScope()能确保Scoped服务在请求结束后正确释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:07:07