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
相关产品推荐
相关产品推荐

