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

.NET Web API控制器无法通过单实例更新类变量的问题排查

问题根源

.NET Web API中,控制器默认是瞬态(Transient)生命周期——每收到一次HTTP请求,框架都会创建一个全新的ConnectionController实例。你在构造函数里手动new GetLabels(),导致两次请求(添加和删除)对应完全独立的GetLabels对象,第二次请求里的字典自然是空的。

另外你的代码存在一个编译错误:RemoveLabels方法里调用的getlabels.Remove(...),字段名实际是getLabels(大写L),大小写不匹配会导致代码无法正常运行。

解决方案

要让多次请求共享同一个GetLabels实例,需要通过依赖注入管理它的生命周期,而非在控制器内手动实例化。

1. 注册GetLabels的生命周期

根据你的业务需求选择合适的生命周期:

  • 单例(Singleton):整个应用运行期间仅存在一个实例,所有请求共享,适合存储全局状态。
  • 作用域(Scoped):每个请求周期内对应一个实例,同一请求内的服务共享,但不同请求不共享。

在.NET 6+的Program.cs中注册服务:

var builder = WebApplication.CreateBuilder(args);

// 注册为单例
builder.Services.AddSingleton<GetLabels>();
// 若需每个请求内共享,可注册为作用域
// builder.Services.AddScoped<GetLabels>();

builder.Services.AddControllers();
// ...其他配置代码

2. 修改控制器构造函数注入

将GetLabels通过构造函数注入,替代手动实例化的方式:

[Route("api/[controller]")]
[ApiController]
public class ConnectionController : ControllerBase
{
    private readonly GetLabels _getLabels;

    // 构造函数注入GetLabels实例
    public ConnectionController(GetLabels getLabels)
    {
        _getLabels = getLabels;
    }

    [HttpPost]
    public IActionResult BuildLabels()
    {
        _getLabels.Add(key, value);
        return Ok();
    }
    
    [HttpPost("{id}")]
    public IActionResult RemoveLabels()
    {
        _getLabels.Remove(key, value);
        return Ok();
    }     
}

如果选择单例模式,需注意GetLabels内的字典操作要保证线程安全——建议用ConcurrentDictionary替换普通Dictionary,避免多请求并发访问时出现异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:15:19