【问题标题】:How can I use a Windows environment variable in my .NET Core API?如何在 .NET Core API 中使用 Windows 环境变量?
【发布时间】:2019-04-30 19:41:41
【问题描述】:

我们正在创建一个 .NET Core 2.1 应用程序,其中包含一个连接到 SQL Server 数据库的 Web API 项目。

在将我的连接字符串存储在可能的最安全位置时,我正试图正确使用环境变量。

当我听说我可以使用环境变量来存储诸如连接字符串之类的东西时,听起来真的很棒。它是安全的,我们可以让变量因开发人员而异,在登台和生产环境中也有所不同。这很有用,因为它们的 SQL Server 实例的名称并不相同。

但是当我现在向我的 Windows 环境变量添加一个连接字符串时,如下所示:

或者像这样通过 PowerShell:

setx CUSTOMCONNSTR_MyContextDb "Server=.\\MYSQLSERVER;Database=MyDb_local;Trusted_Connection=True;ConnectRetryCount=0"

我试着像这样得到它:

var connectionString = Configuration.GetConnectionString("MyContextDb");

但这不起作用。字符串为空。

只有在我转到项目属性时将 CUSTOMCONNSTR_MyContextDb 变量和值添加到环境变量中,然后在“调试”选项卡上输入环境变量,我才能使这行代码工作。这基本上只是将它们设置在 launchSettings.json 文件中。这似乎几乎没有比 appsettings.json 更好的位置(或者是吗?)。

我是否误解了 .NET Core 中环境变量的使用?我可以不使用 windows 定义的环境变量吗?还是只能在我的 IIS 服务器上使用真实的 Windows 环境变量?

看起来可以,因为当我调试并查看配置对象时,我看到了一个包含 80 多个环境变量的列表。

作为参考,this post 和一个简短的 YouTube 剪辑帮助我更好地理解了这方面的概念,但我并没有完全掌握所有内容,希望你能提供帮助。

【问题讨论】:

  • Configuration这里应该是启动文件中IConfiguration的实例
  • 当您对帖子投反对票时,请详细说明原因
  • @AdamVincent,是的,它是 IConfiguration 的实现

标签: c# asp.net-core environment-variables


【解决方案1】:

Configuration.* 从应用程序配置文件中读取。你正在寻找

Environment.GetEnvironmentVariable("CUSTOMCONNSTR_MyContextDb")

对于“连接字符串应该存储在哪里”的问题,不是那么容易回答的。这是一个意见问题,像往常一样这取决于。

如果预计只有一点配置数据会发生变化,为了方便起见,我会考虑只使用 appsettings.json。如果需要考虑更多配置选项,例如在本地运行和在 Azure 上运行,我可能会考虑采用覆盖方法,例如 this. 另一个考虑因素是从事同一项目的团队成员的数量。每个都可能有自己的具有不同设置的本地数据库实例。在这种情况下,SecretManager 可能是一个不错的选择。

到目前为止,您可能已经看到了许多用于疯狂的工具和方法。不幸的是,我没有比其他人更能推荐的包罗万象的解决方案。我会坚持你现在正在尝试的方法,直到它不起作用为止。

我不相信您误解了这个概念,除了“windows 定义的环境变量”和其他短语“我的 IIS 服务器上的真实环境变量”。 Windows 和 IIS 仍然只是别人编写的软件。它们没有比您的环境变量更多或更少的价值。

我从未在您提到的选项卡中设置环境变量,所以我不知道它存储在 launchSettings.json 中。稍后我将不得不对此进行深入研究。

【讨论】:

  • 这确实有效,但也不能完全回答我的所有问题,请注意,这需要重新启动 Visual Studio! (顺便说一句,我没有投票给你)
  • 这只需要重新启动 Visual Studio,因为 Visual Studio 和所有应用程序一样,只会在启动时检索 env 变量。如果您说使用“dotnet run”启动您的应用程序,您就不会遇到问题。
  • 好的,所以我们有一个运行 IIS 的 VPS,我想将我的连接字符串安全地存储在该机器上的某个地方,我找不到任何好的建议(每个人都说要使用 Azure,但我们不这样做)不要那样做)。你有什么建议吗?
  • 没有 Azure 密钥库?我能想到的最好的建议是在本地机器上加密设置文件。在this post上有一个如何创建自定义配置提供程序的示例
  • 最后我通过IIS管理器将环境变量添加到IIS网站:选择网站,打开配置编辑器,打开system.webServer/aspNetCore的设置,在那里你可以设置环境变量(需要重启网站)
【解决方案2】:

我认为这里对环境变量有明显的误解。

在谈论单个 ASP 应用程序的配置时,特别是由于 Docker 是一个东西等,环境变量是指存储在 appsettings.json 或 launchsettings.json 中的特定应用程序的配置变量。

Windows 环境变量在这里并不意味着,并且出于很多原因,通常不会将 ASP.NET Core 应用程序考虑在内。

你的sn-p在那里:

var connectionString = Configuration.GetConnectionString("MyContextDb");

正在从 appsettings.json 中的“ConnectionString”部分显式读取数据。你不能覆盖它。

在我看来,拥有“每个用户”设置的最佳方法是使用一个全局 appsettings.json,其值对所有开发人员/用户都有效,并且每个用户都有自己的 appsettings_develop.json,其中包含他/她的个人连接字符串等在。个人的被添加到 gitignore 并且没有提交并且只存在于用户的机器上。

我建议不要使用主机系统中的任何环境变量(例如,您的 Windows User 环境变量),因为您需要确保它们存在于您想要使用的任何地方你的应用程序,如果你把它放在 Docker 中,Docker 容器需要它们等等,不能使用 GitHub 或 TFS 提交环境变量。 JSON 配置是您最好的选择。

【讨论】:

  • 如果您在 WebHost builder 中设置了 AddEnvironmentVariables,GetConnectionString 也可以从 launchsettings.json 中读取
【解决方案3】:

GetConnectionString 方法的代码类似于this:

public static string GetConnectionString(this IConfiguration configuration, string name)
{
    return configuration?.GetSection("ConnectionStrings")?[name];
}

这表明连接字符串本身必须位于ConnectionStrings 部分中。由于您的 IConfiguration 实例实际上代表了 string 到 string 的字典,因此最终会寻找一个名为 ConnectionStrings:[name] 的键。

要解决找不到环境变量的问题,您应该将其命名为ConnectionStrings:MyContextDb(您也可以使用__ 代替:,但: 更常见)。

当我第一次阅读您的问题时,我很惊讶将它添加到 launchSettings.json 文件中使其工作,但我发现 CUSTOMCONNSTR_MyContextDb 的这个值正在为您转换为 ConnectionStrings:MyContextDb。您可以通过以下方式确认这一点:

new ConfigurationBuilder()
    .AddEnvironmentVariables()
    .Build()
    .AsEnumerable()
    .ToList()
    .ForEach(x => Console.WriteLine("{0} => {1}", x.Key, x.Value));

这只是查看已添加到 IConfiguration 实例中的所有键/值对的一种非常便宜且令人愉快的方式。

【讨论】:

    猜你喜欢
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    • 2018-03-08
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    相关资源
    最近更新 更多