如何在环境变量中正确存储连接字符串,以便通过生产ASP.Net Core MVC应用程序进行检索

我正在使用ASP.NET Core MVC应用程序,我的连接字符串存在问题。

我在生产服务器ASPNETCORE_ENVIRONMENT变量设置为Production ,而我的生产服务器是运行IIS的Windows Server 2012R2。 我还在生产服务器上安装了DotNetCore.1.0.4_1.1.1-WindowsHosting.exe。

在开发过程中,我使用UserSecrets来保存我的连接字符串。 这工作正常。

对于生产,我想在生产服务器上的环境变量中使用连接字符串,这就是我遇到问题的地方。 我怀疑它可能与构建环境变量的方式不同。

当我尝试在生产中访问数据库时,我得到一个错误,表明它无法解析连接字符串。

 An exception occurred in the database while iterating the results of a query. System.ArgumentException: Keyword not supported: '"server'. at System.Data.Common.DbConnectionOptions.ParseInternal(Dictionary`2 parsetable, String connectionString, Boolean buildChain, Dictionary`2 synonyms) at System.Data.Common.DbConnectionOptions..ctor(String connectionString, Dictionary`2 synonyms) at System.Data.SqlClient.SqlConnectionString..ctor(String connectionString) 

如果我将连接字符串放在appSettings.json ,生产服务器就可以正常工作。

所以,这是我的appSettings.json文件的一个示例,显示了在生产中工作的连接字符串;

 { "ConnectionStrings": { "TestDb": "Server=TestServer;Database=TestDb;Persist Security Info=True;User ID=TestUser;Password=testpassword;MultipleActiveResultSets=true" }, ... ... ... } } 

如果我将此appSettings.json文件部署到生产中,它可以正常工作。

在我的ASP.Net Core应用程序中,在Startup.cs文件中,我有以下内容:

 public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); if (env.IsDevelopment()) { // For more details on using the user secret store see https://go.microsoft.com/fwlink/?LinkID=532709 builder.AddUserSecrets(); } builder.AddEnvironmentVariables(); Configuration = builder.Build(); } 

我的理解是列出的最后一个builder.add …具有优先级,所以在我的情况下,如果环境中存在连接字符串,它应优先于appsettings中的任何内容。

所以在生产中,如果我使用以下appSettings.config文件;

 { "ConnectionStrings": { "TestDb": "Placeholder for connection string. Overridden by User Secrets in Development and Environment Variables in Production. " }, ... ... ... } } 

如果我有连接字符串的环境变量,那么我在appsettings.json文件中的ConnectionStrings:TestDb的值是什么并不重要。

下面列出的是我正在使用的环境变量;

 Variable Value ConnectionStrings:TestDb "Server=TestServer;Database=TestDb;Persist Security Info=True;User ID=TestUser;Password=testpassword;MultipleActiveResultSets=true" 

但是,当我使用此设置时,当我尝试访问数据库时指示它无法解析连接字符串时出现错误。

我必须假设问题是我在环境变量中指定连接字符串的方式,但经过一段时间在线搜索后,我无法找到环境变量值应该是什么样子的示例。 例如,我是否需要在整个字符串周围放置前导和尾随单引号? 连接字符串的各个部分是否需要单引号或双引号?

任何帮助,例如在环境变量中定义的正确连接字符串的示例,都将非常感激。

您的连接变量中设置了错字/错误值。

在您粘贴的输出中可以看到:

 Variable Value ConnectionStrings:TestDb "Server=TestServer;Database=TestDb;Persist Security Info=True;User ID=TestUser;Password=testpassword;MultipleActiveResultSets=true" 

这可能在设置变量via时发生

 $env:ConnectionStrings:MyDb = """Server=...""" 

正确的方法是在没有引号的情况下设置它。

 $env:ConnectionStrings:MyDb = "Server=..." 

旧答案(对于可能搜索类似问题的其他用户)

连接字符串的约定是Azure Web Apps使用的SQLCONNSTR_MYSQLCONNSTR_SQLAZURECONNSTR_CUSTOMCONNSTR_ ,但也适用于自托管,VM或任何其他云提供程序。

因此,如果您有一个名为CUSTOMCONNSTR_TestDb的环境变量,它将与在appsettings.json中定义它一样。

 { "connectionStrings": { "TestDb": "..." } } 

如果在.UseJsonFile(...)之后调用AddEnvironmentVariables() ,它也会覆盖其中的值。 上次注册获胜。

 var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) // This one needs to be last .AddEnvironmentVariables(); 

您还可以使用其他变量来覆盖配置值。 IIRC。 ASPNETCORE_是默认前缀(但您可以在AddEnvironmentVariables("MY_")更改它)。

因此, ASPNETCORE_MySettings会覆盖Configuration["MySettings"] (或Configuration.Get("MySettings") )和ASPNETCORE_My__Settings (在Linux上使用双下划线用于级别层次结构,读取位置:用于获取配置 – Linux禁止变量名中的冒号)覆盖Configuration["My:Settings"]如此相同

 { "my": { "settings": "..." } } 

除非他们最近改变了。

FWIW:据我记忆,环境变量/配置键名称不区分大小写。

在您的配置中,您有以下这一行:

 .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); 

这告诉您的配置系统可能存在一个JSON文件,其中包含特定于环境的设置。 所以你只需要一个名为appSettings.Production.config的生产盒上存在的文件,其中包含以下内容:

 { "ConnectionStrings": { "TestDb": "Server=...;Catalog=...;Etc=..." } } 

此处的值将覆盖基本JSON设置文件中指定的任何内容。

如果您不想存储在appsettings中,请将其存储在文件C:\ Windows \ System32 \ inetsrv \ config \ applicationHost.config中。 它将能够工作。