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

作用域服务对象在中间件赋值后并行请求时有时为空的问题

问题原因及解决方案

核心原因

你遇到的问题大概率是**UserSettings类内部使用了静态成员存储用户信息**。虽然你用AddScoped注册了服务,每个请求会生成独立的UserSettings实例,但如果类里的属性是静态的,所有实例都会共享这部分状态——并行请求时,多个请求的设置操作会互相覆盖,最终只有一个请求的信息能保留下来。

另外也有可能是注册服务时误使用了AddSingleton(但你明确说明用了AddScoped,这条可能性极低),或者中间件里的设置逻辑误操作了全局共享资源。

解决办法

1. 修正UserSettings类的实现

把类里的静态成员改成实例成员,让每个请求的UserSettings实例拥有独立的状态:

public interface IUserSettings
{
    string UserId { get; set; }
    // 其他用户信息属性
}

public class UserSettings : IUserSettings
{
    // 用实例属性,每个Scoped实例独立存储
    public string UserId { get; set; }
    // 其他实例属性...
}

2. 确保中间件逻辑正确

中间件的InvokeAsync方法里,直接操作注入的当前请求专属的userSettings实例即可,不需要额外处理线程问题——因为AddScoped已经保证每个请求有独立的实例:

public async Task InvokeAsync(HttpContext context, IUserSettings userSettings, IHttpClientFactory httpClientFactory)
{
    // 示例:从请求中获取用户ID并设置到当前实例
    var userId = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
    userSettings.UserId = userId;

    // 继续处理请求
    await _next(context);
}

3. 关于HttpContext.Items的正确用法

如果你已经改用HttpContext.Items存储,要确保存入和取出的是当前请求的上下文:

  • 中间件存入:
    context.Items["UserSettings"] = userSettings;
    
  • 后续在控制器/服务中取出(需要注入IHttpContextAccessor):
    public class SomeService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
    
        public SomeService(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
    
        public void DoSomething()
        {
            if (_httpContextAccessor.HttpContext?.Items.TryGetValue("UserSettings", out var settings) == true && settings is IUserSettings userSettings)
            {
                // 使用userSettings
            }
        }
    }
    

注意:使用IHttpContextAccessor需要先注册服务:

services.AddHttpContextAccessor();

不过更推荐用AddScoped的方式,因为它更符合依赖注入的设计,代码可读性和可测试性更好,只要类本身是实例成员的实现,就不会有并行请求的冲突问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:33:27