.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加载与格式:
- 在Program.cs中添加日志验证连接字符串加载情况:
#if DEBUG var connStr = builder.Configuration.GetConnectionString("HomeDatabase"); Console.WriteLine($"Loaded debug connection string: {connStr}"); #endif - 检查Secrets.json的键名与格式是否正确,确保结构为:
{ "ConnectionStrings:HomeDatabase": "你的调试环境连接字符串" }
- 在Program.cs中添加日志验证连接字符串加载情况:
确认AddUserSecrets的加载顺序:确保
AddUserSecrets在配置链中处于正确位置,避免后续配置源覆盖或清空连接字符串配置。
内容的提问来源于stack exchange,提问作者SkeeterQuill
相关产品推荐
相关产品推荐

