简体   繁体   English

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

[英]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=..."

Old answer (for other users who may search for similar issues) 旧答案(对于可能搜索类似问题的其他用户)

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.

相关问题 在环境变量 ASP.Net MVC 应用程序中正确存储数据库连接字符串 - Correctly storing db connection strings in environment variables ASP.Net MVC Apps 我应该在哪里存储我的 ASP.NET Core 应用程序生产环境的连接字符串? - Where should I store the connection string for the production environment of my ASP.NET Core app? asp.net 核心通过 ENV 变量覆盖连接字符串 - asp.net core override connection strings via ENV variables 如何在“生产”环境中Web部署ASP.NET Core应用程序? - How to WebDeploy an ASP.NET Core application in “Production” environment? 如何解决 docker-compose 环境变量不起作用 ASP.Net Core MVC - How to solve docker-compose environment variables not working ASP.Net Core MVC Asp.net Core MVC - 数据检索问题 - Asp.net Core MVC - Data retrieval question ASP.NET Core Apps中的环境变量 - Environment Variables in ASP.NET Core Apps 如何在共享服务器上托管的 ASP.Net Core 3.1 应用程序中存储生产机密,如连接字符串 - How can I store production secrets like connection string in ASP.Net Core 3.1 application, hosted on a shared server asp.net core 1 appsettings.production.json没有更新连接字符串 - asp.net core 1 appsettings.production.json not updating connection strings ASP.Net Core Web Api - 使用生产和测试数据库连接字符串 - ASP.Net Core Web Api - Use production and test database connection strings
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM