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

.NET 8 ASP.NET Core应用添加MySQL健康检查时触发ArgumentNullException(连接字符串为空)

.NET 8 ASP.NET Core应用添加MySQL健康检查时触发ArgumentNullException(连接字符串为空)

这个问题的核心是你配置加载顺序搞反了,而且在Azure App Configuration的配置还没加载完成时,就提前读取了连接字符串,导致传给MySQL健康检查的参数是空值,触发了ArgumentNullException。

问题出在哪?

看你的代码流程就能发现问题:

  1. 你先从本地配置里读取了ConnectionStringsSettings并赋值给connectionStringsOptions
  2. 之后才把Azure App Configuration添加到配置源中
  3. 最后用提前读取的空连接字符串调用AddMySql

这时候connectionStringsOptions.MyConnectionString只有本地配置里的值(如果本地没有就是null)——因为Azure的配置是在你读取配置之后才添加的,根本没机会覆盖这个变量的值。后面的builder.Services.Configure<ConnectionStringsSettings>只是注册了配置绑定规则,但不会更新你已经拿到的connectionStringsOptions变量。

两种可行的解决方案

方案1:调整配置加载顺序(推荐)

先把Azure App Configuration添加到配置源,再读取连接字符串。这样读取配置的时候就已经包含了从Azure拉取的内容:

if (!builder.Environment.IsDevelopment())
{
    // 第一步:先把Azure App Configuration加入配置源
    builder.Configuration.AddAzureAppConfiguration(options =>
    {
        options.Connect(new Uri(azureAppConfigurationOptions.Uri), new 
              DefaultAzureCredential(defaultAzureCredentialOptions));
    
        options.ConfigureKeyVault(kv =>
        {
            kv.SetCredential(new DefaultAzureCredential(defaultAzureCredentialOptions));
        });
    });
    
    // 第二步:再从包含Azure配置的Configuration里读取连接字符串
    builder.Services.AddAzureAppConfiguration();
    IConfigurationSection configurationConnectionStringsSection = builder.Configuration.GetSection(ConnectionStringsSettings.Section);
    builder.Services.Configure<ConnectionStringsSettings>(configurationConnectionStringsSection);
    ConnectionStringsSettings? connectionStringsOptions = configurationConnectionStringsSection.Get<ConnectionStringsSettings>()
        ?? throw new InvalidOperationException($"Invalid settings for {nameof(ConnectionStringsSettings)}");

    builder.Services
        .AddHealthChecks()
        .AddApplicationStatus("Self")
        .AddMySql(connectionStringsOptions.MyConnectionString);
}

方案2:延迟加载连接字符串(适合无法调整顺序的场景)

使用AddMySql的重载方法,通过服务容器动态获取连接字符串——这样连接字符串会在健康检查执行时才去读取,而不是启动时:

builder.Services
    .AddHealthChecks()
    .AddApplicationStatus("Self")
    .AddMySql(
        // 从服务容器中获取已绑定的最新配置
        sp => sp.GetRequiredService<IOptions<ConnectionStringsSettings>>().Value.MyConnectionString,
        // 可按需配置健康查询、超时等参数
        healthQuery: "SELECT 1;",
        timeout: TimeSpan.FromSeconds(5)
    );

这种方式不需要提前读取connectionStringsOptions,而是在健康检查真正执行时才从IOptions<ConnectionStringsSettings>里拿值,这时候Azure的配置已经加载完成,绑定也完全生效了。

额外提醒

builder.Services.Configure<ConnectionStringsSettings>只是注册了配置的绑定规则,不会自动更新你已经提前读取到变量里的配置值。如果配置源(比如Azure App Configuration)是在读取变量之后添加的,变量里的值不会同步更新,这是很多人容易踩的小坑。

备注:内容来源于stack exchange,提问作者Terai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:23:04