EFCore "Value cannot be null. (Parameter 'connectionString')" 如果值在环境变量中

EFCore "Value cannot be null. (Parameter 'connectionString')" if value is in environment variables

在 Asp.NET 核心 Web 应用程序中,使用 EFCore-5,我有以下 ConfigureServices

// ...
services.AddRouting(options => options.LowercaseUrls = true);

// get the connection string from secrets/env.variables
string connectionString = Configuration.GetConnectionString("MyWebApp"); /// <<< HERE
services.AddDbContext(connectionString);

services.AddDatabaseDeveloperPageExceptionFilter();    
services.AddControllersWithViews();
// ...

还有AddDbContext扩展方法:

public static void AddDbContext(this IServiceCollection services, string connectionString) =>
        services.AddDbContext<ApplicationDbContext>(options =>
        {
            options.UseSqlServer(connectionString,    /// <<< HERE
                providerOptions =>
                {
                    providerOptions
                        .EnableRetryOnFailure(
                            maxRetryCount: 5, 
                            maxRetryDelay: TimeSpan.FromSeconds(30),
                            errorNumbersToAdd: null)
                        .UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
                });
            options.EnableSensitiveDataLogging();

如果我将连接字符串放在 appsettings.Production.json 中,站点运行良好,但是一旦我删除它并放入 EnvironmentVariables,页面就会给我 500 错误 并且我拥有的日志:

System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString') at Microsoft.EntityFrameworkCore.Utilities.Check.NotEmpty(String value, String parameterName) at Microsoft.EntityFrameworkCore.SqlServerDbContextOptionsExtensions.UseSqlServer(DbContextOptionsBuilder optionsBuilder, String connectionString, Action`1 sqlServerOptionsAction)

错误指向上面代码中用第二个HERE标记的行。

我这样设置环境变量:

默认配置加载前缀为 DOTNET_ASPNETCORE_ 的环境变量和命令行参数。

基于此,你应该使用

ASPNETCORE_ConnectionStrings__MyWebAppASPNETCORE_ConnectionStrings:MyWebApp

可以配置自定义前缀 AddEnvironmentVariables:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

我终于成功了。我的解决方案是使用 SQLCONNSTR_MyWebApp(作为 System,而不是 User 变量)和 after 应用程序环境变量的任何更改,要将其考虑在内,从命令提示符 (docs)

执行 net stop was /y,然后执行 net start w3svc

从 IIS 管理器重新启动 IIS 不会重新加载 环境变量中的更改...