[英]How to correctly store connection strings in environment variables for retrieval by production ASP.Net Core MVC applications
I am working on an ASP.NET Core MVC application and I am having an issue with my connection strings. 我正在使用ASP.NET Core MVC应用程序,我的连接字符串存在问题。
I have an ASPNETCORE_ENVIRONMENT
variable set to Production
on my production server and my production server is a Windows Server 2012R2 running IIS. 我在生产服务器
ASPNETCORE_ENVIRONMENT
变量设置为Production
,而我的生产服务器是运行IIS的Windows Server 2012R2。 I also have the DotNetCore.1.0.4_1.1.1-WindowsHosting.exe installed on the production server. 我还在生产服务器上安装了DotNetCore.1.0.4_1.1.1-WindowsHosting.exe。
During development, I am using UserSecrets
to hold my connection string. 在开发过程中,我使用
UserSecrets
来保存我的连接字符串。 This is working properly. 这工作正常。
For production, I want my connection strings in environment variables on my production server and this is where I am having an issue. 对于生产,我希望我的生产服务器上的环境变量中的连接字符串,这是我遇到问题的地方。 I suspect that it may be in the way I am structuring the environment variable.
我怀疑它可能是我构建环境变量的方式。
When I try to access the database in production I get an error indicating basically that it can't cannot parse the connection string. 当我尝试在生产中访问数据库时,我得到一个错误,表明它无法解析连接字符串。
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)
If I put the connection string in appSettings.json
, the production server works just fine. 如果我将连接字符串放在
appSettings.json
,那么生产服务器就可以正常工作。
So, here is an example of my appSettings.json
file showing the connection string that works in production; 所以,这是我的
appSettings.json
文件的一个例子,显示了在生产中工作的连接字符串;
{
"ConnectionStrings": {
"TestDb": "Server=TestServer;Database=TestDb;Persist Security Info=True;User ID=TestUser;Password=testpassword;MultipleActiveResultSets=true"
},
...
...
...
}
}
If I deploy this appSettings.json
file to production, it works OK. 如果我将此
appSettings.json
文件部署到生产中,它可以正常工作。
In my ASP.Net Core application, in the Startup.cs file, I have the following; 在我的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<Startup>();
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
My understanding is that the last builder.add... listed has priority, so in my case, if a connection string exists in the environment, it should take priority over anything in appsettings. 我的理解是列出的最后一个builder.add ...具有优先级,所以在我的情况下,如果环境中存在连接字符串,它应优先于appsettings中的任何内容。
So in production, if I use the following appSettings.config file; 所以在生产中,如果我使用以下appSettings.config文件;
{
"ConnectionStrings": {
"TestDb": "Placeholder for connection string. Overridden by User Secrets in Development and Environment Variables in Production. "
},
...
...
...
}
}
It should not matter what I have as a value for ConnectionStrings:TestDb
in that appsettings.json
file if I have an environment variable for the connection string. 如果我有一个连接字符串的环境变量,那么我在
appsettings.json
文件中作为ConnectionStrings:TestDb
的值应该没关系。
Listed below is the environment variable I am using; 下面列出的是我正在使用的环境变量;
Variable Value
ConnectionStrings:TestDb "Server=TestServer;Database=TestDb;Persist Security Info=True;User ID=TestUser;Password=testpassword;MultipleActiveResultSets=true"
However, when I use this setup, I get an error when I try to access the database indicating that it can't parse the connection string. 但是,当我使用此设置时,当我尝试访问数据库时指示它无法解析连接字符串时出现错误。
I have to assume that the problem is the way I have the connection string specified in the environment variable, but after quite a while searching online, I have not been able to find an example of exactly what the environment variable value should look like. 我必须假设问题是我在环境变量中指定连接字符串的方式,但经过一段时间在线搜索后,我无法找到环境变量值应该是什么样子的示例。 For example, do I need to put leading and trailing single quotes around the entire string?
例如,我是否需要在整个字符串周围放置前导和尾随单引号? Does individual sections of the connection string need single or double quotes?
连接字符串的各个部分是否需要单引号或双引号?
Any help, such as an example of a proper connection string defined in an environment variable, would be greatly appreciated. 任何帮助,例如在环境变量中定义的正确连接字符串的示例,都将非常感激。
There is a typo/wrong value set in your connection variables. 您的连接变量中设置了错字/错误值。
Which can be seen in this output you pasted: 在您粘贴的输出中可以看到:
Variable Value
ConnectionStrings:TestDb "Server=TestServer;Database=TestDb;Persist Security Info=True;User ID=TestUser;Password=testpassword;MultipleActiveResultSets=true"
This likely happend while setting the variable via 这可能在设置变量via时发生
$env:ConnectionStrings:MyDb = """Server=..."""
the correct way is to set it without the quotation marks. 正确的方法是设置它没有引号。
$env:ConnectionStrings:MyDb = "Server=..."
The convention for connection strings is SQLCONNSTR_
, MYSQLCONNSTR_
, SQLAZURECONNSTR_
and CUSTOMCONNSTR_
which are used by Azure Web Apps, but should also work for self-hosting, VMs or any other cloud provider. 连接字符串的约定是Azure Web Apps使用的
SQLCONNSTR_
, MYSQLCONNSTR_
, SQLAZURECONNSTR_
和CUSTOMCONNSTR_
,但也适用于自托管,VM或任何其他云提供程序。
So if you have an environment variable called CUSTOMCONNSTR_TestDb
it will be the same as defining it in appsettings.json in 因此,如果您有一个名为
CUSTOMCONNSTR_TestDb
的环境变量,它将与在appsettings.json中定义它一样。
{
"connectionStrings": {
"TestDb": "..."
}
}
It will also override the value inside it, if AddEnvironmentVariables()
is called after .UseJsonFile(...)
. 如果在
.UseJsonFile(...)
之后调用AddEnvironmentVariables()
,它还将覆盖其中的值。 Last registration wins. 上次注册获胜。
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();
You can also use other variables to override configuration values. 您还可以使用其他变量来覆盖配置值。 iirc.
IIRC。
ASPNETCORE_
is the default prefix (but you can change it in the AddEnvironmentVariables("MY_")
). ASPNETCORE_
是默认前缀(但您可以在AddEnvironmentVariables("MY_")
更改它)。
So a ASPNETCORE_MySettings
overrides Configuration["MySettings"]
(or Configuration.Get("MySettings")
) and ASPNETCORE_My__Settings
(use double underscore for level hierarchy on Linux, read where :
is used to obtain the config - Linux disallows colon in variable names) overrides Configuration["My:Settings"]
so same as 因此,
ASPNETCORE_MySettings
会覆盖Configuration["MySettings"]
(或Configuration.Get("MySettings")
)和ASPNETCORE_My__Settings
(在Linux上使用双下划线用于级别层次结构,读取位置:
用于获取配置 - Linux禁止变量名中的冒号)覆盖Configuration["My:Settings"]
如此相同
{
"my": {
"settings": "..."
}
}
Unless they changed that recently. 除非他们最近改变了。
FWIW: Environment variables/configuration key names are case-insensitive as far as I remember. FWIW:据我记忆,环境变量/配置键名称不区分大小写。
In your configuration you have this line: 在您的配置中,您有以下这一行:
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
This is telling your configuration system that there might be a JSON file that exists with environment specific settings in it. 这告诉您的配置系统可能存在一个JSON文件,其中包含特定于环境的设置。 So you only need a file that exists on the production box called
appSettings.Production.config
containing something like this: 因此,您只需要一个名为
appSettings.Production.config
的生产框上存在的文件,其中包含以下内容:
{
"ConnectionStrings": {
"TestDb": "Server=...;Catalog=...;Etc=..."
}
}
The values in here will override anything specified in the base JSON settings file. 此处的值将覆盖基本JSON设置文件中指定的任何内容。
if you don't want to store in appsettings, store it in the file C:\\Windows\\System32\\inetsrv\\config\\applicationHost.config. 如果您不想存储在appsettings中,请将其存储在文件C:\\ Windows \\ System32 \\ inetsrv \\ config \\ applicationHost.config中。 It will be able to work.
它将能够工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.