问题描述
我偶然发现了一个 ASP.NET Core 3.1 应用程序的奇怪情况:launchSettings.json 中定义的 environmentvariables 未设置(例如,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","environmentvariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}
我正在使用 IIS Express
。
我调查或尝试过的事情:
-
将项目拉到另一台机器上,它按预期工作:
Environment.GetEnvironmentvariable("ASPNETCORE_ENVIRONMENT"
是"Development"
。 -
在同一台机器上运行一个非常相似的项目(几乎相同的配置),它按预期工作
-
重启机器,问题依旧
-
将工作项目与非工作项目 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
解决方法
您将操作系统的环境变量与 .NET Core 运行时环境混淆了。他们有相同的名字,一个可以晋升为另一个,但他们不一样。
launchSettings.json 中的环境变量("runtime environment" 或 "host configuration values")不会提升为操作系统的实际环境变量,后者您可以通过 Environment.GetEnvironmentVariable()
读取。>
您可以通过 ASPNETCORE_ENVIRONMENT
或 IHostingEnvironment.Environment
读取应用程序的 IWebHostEnvironment.EnvironmentName
。
总结:您不应该使用 Environment.GetEnvironmentVariable()
从操作系统的环境变量中读取 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")
始终查看进程级别,而不会查看操作系统级别。您当然可以通过使用 GetEnvironmentVariable(String,EnvironmentVariableTarget)
来更改它,但这不会像@CodeCaster 提到的那样对您有所帮助。因此,使用 IWebHostEnvironment
来获取环境名称应该足以满足您的情况,但您可能已经在机器级别或其他内容中设置了 DOTNET_ENVIROMENT,因此请确保知道您特别需要什么。
但是,IWebHostEnviroment
怎样才能检索到它呢?
这是因为那些“环境名称”不是环境变量。 ASP.Net Core 确实设置了任何类型的环境变量。相反,它把它定义为一种让你说好的这是一个开发环境,这是一个生产环境的方式。它可以从机器或用户环境变量中读取数据,但不会创建任何类型的变量。
所以你在使用 IIS 时不能读取这些环境变量的原因是因为这些环境变量首先不存在。
此外,IWebHostEnvironment
不会以某种方式神奇地读取环境变量。他们只是从 lauchsettings.json
加载它,所以同样没有环境变量设置。
更具体地说,在源代码中:
hostingEnvironment.EnvironmentName =
options.Environment ??
hostingEnvironment.EnvironmentName;
它要么由您定义的选项检索,如果您没有定义它,那么它将保持不变。
此外,终止进程后进程环境变量不会持续存在,因此无需重新启动机器或清理这些变量。 (一般评论)