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

.NET 8使用User Secrets时连接字符串未初始化异常排查

调试模式下使用Secrets.json时DbContext二次调用连接字符串为空问题

硬编码连接字符串、发布模式下用Azure Key Vault时项目运行完全正常,但调试模式依赖Secrets.json时,部分端点正常,其他端点抛出以下错误:

System.InvalidOperationException: The ConnectionString property has not been initialized.
   at Microsoft.Data.SqlClient.SqlConnection.PermissionDemand()
   at Microsoft.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection)
   at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
   at Microsoft.Data.SqlClient.SqlConnection.InternalOpenAsync(CancellationToken cancellationToken)

断点调试发现:首次获取连接字符串正常,但DbContext被第二次调用时,connectionString会突然变为null。新增用于处理令牌的DbContext和数据库后,同样出现该空值错误,推测Secrets资源可能会被占用至使用它的上下文结束。

当前代码实现

Program.cs

var builder = WebApplication.CreateBuilder(args);

#if DEBUG
builder.Configuration.AddUserSecrets<Program>();

#else
var vaultUri = Environment.GetEnvironmentVariable("VaultUri");
var keyVaultEndpoint = new Uri(vaultUri);
builder.Configuration.AddAzureKeyVault(keyVaultEndpoint, new DefaultAzureCredential());
#endif

DbContext配置代码

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{

#if DEBUG
    string connectionString = _configuration.GetConnectionString("HomeDatabase");

#else
    string connectionString = _configuration.GetConnectionString("AzureDatabase");
    
#endif
    optionsBuilder.UseSqlServer(connectionString);

}

解决思路

  • 修正DbContext依赖注入生命周期:如果DbContext被注册为Singleton,会导致首次注入后_configuration可能失效。确保DbContext注册为ASP.NET Core默认推荐的Scoped生命周期,同时将配置逻辑移到Program.cs中:

    builder.Services.AddDbContext<YourDbContext>(options => 
    {
        #if DEBUG
            options.UseSqlServer(builder.Configuration.GetConnectionString("HomeDatabase"));
        #else
            options.UseSqlServer(builder.Configuration.GetConnectionString("AzureDatabase"));
        #endif
    });
    

    移除DbContext中OnConfiguring的手动配置代码,避免重复读取配置。

  • 避免在DbContext内部直接依赖IConfiguration:IConfiguration是单例,但如果DbContext生命周期配置错误,会导致后续读取配置异常,统一在Program.cs中完成DbContext的配置更可靠。

  • 验证Secrets.json加载与格式:

    1. 在Program.cs中添加日志验证连接字符串加载情况:
      #if DEBUG
          var connStr = builder.Configuration.GetConnectionString("HomeDatabase");
          Console.WriteLine($"Loaded debug connection string: {connStr}");
      #endif
      
    2. 检查Secrets.json的键名与格式是否正确,确保结构为:
      {
        "ConnectionStrings:HomeDatabase": "你的调试环境连接字符串"
      }
      
  • 确认AddUserSecrets的加载顺序:确保AddUserSecrets在配置链中处于正确位置,避免后续配置源覆盖或清空连接字符串配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 08:50:23