ASP.NET Core 3.1 launchSettings.json 使用 IISExpress 时未在本地开发机器上设置环境变量

ASP.NET Core 3.1 launchSettings.json environment variables are not set on local development machine when using IISExpress

我偶然发现 ASP.NET Core 3.1 应用程序的一个奇怪情况:未设置 launchSettings.json 中定义的环境变量(例如 Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")null)。

launchsettings.json 看起来像这样:

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:60907",
      "sslPort": 44364
    }
  },
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger/index.html",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "MyApp.WebApi": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "swagger/index.html",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    }
  }
}

我正在使用 IIS Express

我调查或尝试过的事情:

  1. 将项目拉到另一台机器上,它按预期工作:Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT""Development"

  2. 运行 在同一台机器上的一个非常相似的项目(几乎相同的配置)并且它按预期工作

  3. 删除了除 IIS Express 之外的所有 launchsettings.json 内容,它仍然存在相同的问题

  4. 使用另一个配置文件启动并且按预期工作

  5. 关闭 Visual Studio -> 删除 .vs 文件夹 -> 重新打开 VS + re运行 项目。问题仍然存在

  6. 重启机器,问题依旧

  7. 在配置文件中添加了其他环境变量,它们也被忽略了

  8. 比较工作项目与非工作项目 IISExpress applicationhost.config 文件,没有发现任何差异(项目路径除外)。

我现在唯一的解决方法是在 Program.cs 中进行本地更改并确保我永远不会提交它,但我正在寻找真正的解决方法:

string originalEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", originalEnv ?? "Development");

我有 运行 的想法可以尝试。我假设它与该特定应用程序的特定机器上的 IIS Express 配置相关,但我在 %userprofile%\My Documents\IISExpress\config\applicationhost.config

中找不到与环境变量相关的任何内容

您将 OS 的环境变量与 .NET Core 运行时环境混淆了。他们同名,一个可以升为另一个,但他们不一样。

launchSettings.json ("runtime environment" or "host configuration values") 中的环境变量不会提升为 OS 的实际环境变量,后者您可以通读 Environment.GetEnvironmentVariable()

您可以通过IHostingEnvironment.EnvironmentIWebHostEnvironment.EnvironmentName阅读应用程序的ASPNETCORE_ENVIRONMENT

回顾一下:您不应该使用 Environment.GetEnvironmentVariable() 从 OS 的环境变量中读取 ASPNETCORE_ENVIRONMENT,因为 .NET Core 环境可以通过不同的方式设置。

相反:在主机初始化期间,ASPNETCORE_ENVIRONMENT 环境变量是从操作系统读取的,但是这个值可以通过不同的方式提供,即通过 launchSettings.json, .vscode/launch.json 或者甚至 use AddCommandLine(args),然后:

dotnet run --environment "Staging"

并且您的 Environment.GetEnvironmentVariable() 将报告错误的值,如果有的话。

添加 @CodeCaster 回答为什么你不能真正检索它以及幕后发生的事情。是的,你可以使用 IWebHostEnvironment 来检索你需要的东西,但是环境名称不是 asp.net 核心设置的环境变量,如果你的 lauchsettings.json 中没有它,它只是从中读取的东西

环境分为 3 个阶段:

  • 机器
  • 用户
  • 进程

现在的区别是 Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") 总是在进程级别查看它 查看 OS 级别。您当然可以通过使用 GetEnvironmentVariable(String, EnvironmentVariableTarget) 来更改它,但这不会像@CodeCaster 提到的那样帮助您。因此,使用 IWebHostEnvironment 获取环境名称应该足以满足您的情况,但您可能已经在机器级别或其他设置中设置了 DOTNET_ENVIROMENT,因此请确保知道您特别需要什么。

But how can IWebHostEnviroment retrieve it?

这是因为那些“环境名称”不是环境变量。 ASP.Net Core 确实设置了任何类型的环境变量。相反,它将它定义为一种让您说好的,这是一个开发环境,这是一个生产环境的方式。它可以从机器或用户环境变量中读取,但它不会创建任何类型的变量。

所以你在使用 IIS 时无法读取这些环境变量的原因是因为这些环境变量本来就不存在。

此外,IWebHostEnvironment 不会以某种方式神奇地读取环境变量。他们只是从 lauchsettings.json 加载它,所以再次没有环境变量设置。

更具体的在源代码中:

            hostingEnvironment.EnvironmentName =
            options.Environment ??
            hostingEnvironment.EnvironmentName;

它要么通过您定义的选项检索,如果您没有定义它,它将保持不变。

此外,进程环境变量在进程终止后不会持续存在,因此无需重启机器或清理这些变量。 (一般评论)