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

ASP.NET Core自定义中间件初始化UserContext并注入控制器求助

解决ASP.NET Core中中间件创建的UserContext注入控制器问题

我来帮你搞定这个问题,其实步骤很清晰,咱们一步步来:

1. 先注册UserContext的服务生命周期

因为每个请求都需要独立的UserContext实例,所以在Program.cs(如果是旧版本项目就是Startup.cs)里把它注册为Scoped服务——这个生命周期刚好和单个请求绑定:

builder.Services.AddScoped<UserContext>();

2. 在自定义中间件里填充UserContext数据

你不用自己手动new UserContext,而是从当前请求的服务容器里拿已经注册好的Scoped实例,再把解码后的token数据填进去:

public class TokenDecoderMiddleware
{
    private readonly RequestDelegate _next;

    public TokenDecoderMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 从请求头获取auth token
        if (context.Request.Headers.TryGetValue("auth", out var token))
        {
            // 这里替换成你实际的token解码逻辑
            var decodedToken = DecodeAuthToken(token.ToString());

            // 拿到当前请求绑定的UserContext实例
            var userContext = context.RequestServices.GetRequiredService<UserContext>();
            
            // 填充解码后的数据
            userContext.UserId = decodedToken.UserId;
            userContext.Role = decodedToken.Role;
            // 其他你需要的属性都可以在这赋值
        }

        // 继续执行后续管道
        await _next(context);
    }

    // 示例解码方法,替换成你自己的实现
    private DecodedTokenModel DecodeAuthToken(string token)
    {
        // 这里写JWT解码或者你的自定义token解析逻辑
        return new DecodedTokenModel { UserId = "u_1001", Role = "Admin" };
    }
}

// 给中间件加个扩展方法,方便注册
public static class TokenDecoderMiddlewareExtensions
{
    public static IApplicationBuilder UseTokenDecoder(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<TokenDecoderMiddleware>();
    }
}

3. 在控制器里直接注入UserContext

现在你可以用两种方式在控制器里获取UserContext,推荐用构造函数注入:

构造函数注入(更符合依赖注入规范)

[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
    private readonly UserContext _userContext;

    // 构造函数里直接注入UserContext
    public UserController(UserContext userContext)
    {
        _userContext = userContext;
    }

    [HttpGet("profile")]
    public IActionResult GetUserProfile()
    {
        // 直接用_userContext里的解码数据
        return Ok(new { 
            UserId = _userContext.UserId, 
            Role = _userContext.Role 
        });
    }
}

方法参数注入(适合单方法使用的场景)

[HttpGet("role")]
public IActionResult GetUserRole([FromServices] UserContext userContext)
{
    return Ok($"当前用户角色:{userContext.Role}");
}

最后注意中间件的注册顺序

一定要把你的UseTokenDecoder中间件放在UseRouting和UseEndpoints之前,这样才能保证控制器处理请求前,token已经被解码并填充到UserContext里:

var app = builder.Build();

// 其他中间件(比如异常处理、静态文件)...
app.UseTokenDecoder(); // 放在路由中间件之前

app.UseRouting();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:15:29