![](/img/trans.png)
[英]ASP.Net Core 2.1 ASPNETCORE_ENVIRONMENT value not reflecting
[英]How to set ASPNETCORE_ENVIRONMENT to be considered for publishing an ASP.NET Core application
当我将我的 ASP.NET Core web 应用程序发布到我的本地文件系统时,它始终采用 production-config 和值为“Production”的 AS.NETCORE_ENVIRONMENT 变量。
我必须如何以及在何处设置 AS.NETCORE_ENVIRONMENT 变量的值,以便它不仅用于调试,而且用于发布? 我已经尝试了以下选项但没有成功:
除了上面提到的选项,还有其他几个解决方案。
1.修改工程文件(.CsProj)文件
MSBuild 支持EnvironmentName
属性,它可以帮助根据您希望部署的环境设置正确的环境变量。 环境名称将在发布阶段添加到web.config中。
只需打开项目文件 (*.csProj) 并添加以下 XML。
<!-- Custom property group added to add the environment name during publish
The EnvironmentName property is used during the publish
for the environment variable in web.config
-->
<PropertyGroup Condition=" '$(Configuration)' == '' Or '$(Configuration)' == 'Debug'">
<EnvironmentName>Development</EnvironmentName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' != '' AND '$(Configuration)' != 'Debug' ">
<EnvironmentName>Production</EnvironmentName>
</PropertyGroup>
上面的代码会将环境名称添加为Development
用于调试配置或未指定配置。 对于任何其他配置,环境名称将是生成的web.config文件中的Production
。 更多细节在这里。
2. 在发布配置文件中添加 EnvironmentName 属性。
我们也可以在发布配置文件中添加<EnvironmentName>
属性。 打开位于Properties/PublishProfiles/{profilename.pubxml}
的发布配置文件。 这将在项目发布时在web.config中设置环境名称。 更多细节在这里。
<PropertyGroup>
<EnvironmentName>Development</EnvironmentName>
</PropertyGroup>
3. 使用dotnet publish
的命令行选项
此外,我们可以将属性EnvironmentName
作为命令行选项传递给dotnet publish
命令。 以下命令将环境变量作为Development
包含在web.config文件中。
dotnet publish -c Debug -r win-x64 /p:EnvironmentName=Development
选项1:
在 Windows 中设置 ASPNETCORE_ENVIRONMENT 环境变量:
命令行 - setx ASPNETCORE_ENVIRONMENT "Development"
PowerShell - $Env:ASPNETCORE_ENVIRONMENT = "Development"
对于其他操作系统,请参阅在 ASP.NET Core 中使用多个环境
选项 2:
如果你想使用web.config
设置 ASPNETCORE_ENVIRONMENT 然后像这样添加aspNetCore
-
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\MyApplication.exe" arguments="" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</configuration>
这是我们可以在运行时设置它的方式:
public class Program
{
public static void Main(string[] args)
{
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
创建您的appsettings.*.json文件。 (示例: appsettings.Development.json 、 appsettings.Staging.json和appsettings.Production.json )
将变量添加到这些文件中。
像往常一样,为每个环境创建一个单独的发布配置文件。
打开PublishProfiles/Development.pubxml文件(命名将基于您命名的发布配置文件)。
只需将标签添加到PublishProfile以设置EnvironmentName变量,剩下的工作由appsettings.*.json文件命名约定完成。
<PropertyGroup> <EnvironmentName>Development</EnvironmentName> </PropertyGroup>
参考: 用于 ASP.NET Core 应用部署的 Visual Studio 发布配置文件 (.pubxml)
请参阅“设置环境”部分。
您应该按照文档中提供的说明使用web.config
。
<aspNetCore processPath="dotnet"
arguments=".\MyApp.dll"
stdoutLogEnabled="false"
stdoutLogFile="\\?\%home%\LogFiles\aspnetcore-stdout">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
<environmentVariable name="CONFIG_DIR" value="f:\application_config" />
</environmentVariables>
</aspNetCore>
请注意,您也可以设置其他环境变量。
ASP.NET Core 模块允许您为 processPath 属性中指定的进程指定环境变量,方法是在 aspNetCore 元素下的 environmentVariables 集合元素的一个或多个 environmentVariable 子元素中指定它们。 本节中设置的环境变量优先于进程的系统环境变量。
这个变量可以保存在 JSON 中。 例如,envsettings.json 内容如下
{
// Possible string values reported below. When empty, it uses the ENV variable value or
// Visual Studio setting.
// - Production
// - Staging
// - Test
// - Development
"ASPNETCORE_ENVIRONMENT": "Development"
}
稍后修改您的program.cs文件,如下所示
public class Program
{
public static IConfiguration Configuration { get; set; }
public static void Main(string[] args)
{
var currentDirectoryPath = Directory.GetCurrentDirectory();
var envSettingsPath = Path.Combine(currentDirectoryPath, "envsettings.json");
var envSettings = JObject.Parse(File.ReadAllText(envSettingsPath));
var environmentValue = envSettings["ASPNETCORE_ENVIRONMENT"].ToString();
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
var webHostBuilder = new WebHostBuilder()
.UseKestrel()
.CaptureStartupErrors(true)
.UseContentRoot(currentDirectoryPath)
.UseIISIntegration()
.UseStartup<Startup>();
// If none is set it use Operative System hosting enviroment
if (!string.IsNullOrWhiteSpace(environmentValue))
{
webHostBuilder.UseEnvironment(environmentValue);
}
var host = webHostBuilder.Build();
host.Run();
}
}
这样,它将始终包含在发布中,您可以根据托管网站的环境更改为所需的值。
此方法也可以在控制台应用程序中使用,因为更改位于文件Program.cs中。
使用最新版本的dotnet
CLI(2.1.400 或更高版本),您只需设置此 MSBuild 属性$(EnvironmentName)
,发布工具就会使用环境名称将 ASPNETCORE_ENVIRONMENT 添加到 web.config。
此外,从 2.2.100-preview1 开始提供 XDT 支持。
示例: https ://github.com/vijayrkn/webconfigtransform/blob/master/README.md
而不是硬连线开发设置,将其添加到您的.csproj
:
<!-- Adds EnvironmentName variable during publish -->
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<EnvironmentName>Development</EnvironmentName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<EnvironmentName>Production</EnvironmentName>
</PropertyGroup>
我使用当前目录来确定当前环境,然后翻转连接字符串和环境变量。 只要您有站点文件夹的命名约定,例如test 、 beta和sandbox ,这就会非常有效。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var dir = Environment.CurrentDirectory;
string connectionString;
if (dir.Contains("test", StringComparison.OrdinalIgnoreCase))
{
connectionString = new ConnectionStringBuilder(server: "xxx", database: "xxx").ConnectionString;
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
}
else
{
connectionString = new ConnectionStringBuilder(server: "xxx", database: "xxx").ConnectionString;
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Production");
}
optionsBuilder.UseSqlServer(connectionString);
optionsBuilder.UseLazyLoadingProxies();
optionsBuilder.EnableSensitiveDataLogging();
}
为了能够为每个站点设置环境,我们在项目中使用的另一个选项是将Parameters.xml文件添加到项目中,其中包含以下内容:
<parameters>
<parameter name="IIS Web Application Name" defaultValue="MyApp" tags="IisApp" />
<parameter name="Environment" description="Environment" tags="">
<parameterEntry kind="XmlFile" scope="Web.config" match="/configuration/location/system.webServer/aspNetCore/environmentVariables/environmentVariable[@name='ASPNETCORE_ENVIRONMENT']/@value" />
</parameter>
</parameters>
该文件的Build Action是Content并且Copy Action是Copy If Newer ,因此它将成为要部署的包的一部分。
然后,为了部署包和设置环境,在 Release 中,在“WinRM - IIS Web App Deployment”任务下(在使用“IIS web app deploy”任务时也同样有效),我们为 msdeploy 设置了额外的参数:
-setParam:kind=ProviderPath,scope=contentPath,value="MySite" -setParam:name="Environment",value="Stage"
这样我们可以有多个版本,都使用相同的工件,但部署为不同的环境。
我不得不手动将这段代码添加到我的主要方法中。 这将基于 Azure 的应用程序设置的环境
static async Task Main(string[] args)
{
...
//set the environment variable based on App Settings
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
builder.UseEnvironment(environment);
通过直接在 Azure 平台上设置这个变量(如果你使用它),我发现它对我有用。
只需选择您的 Web 应用程序 →配置→应用程序设置并添加变量及其值。 然后按保存按钮。
对于 .NET 6,我发现这是最好的解决方案:
var webAppOptions = new WebApplicationOptions()
{
Args = args,
#if DEBUG
EnvironmentName = Environments.Development,
#else
EnvironmentName = Environments.Production,
#endif
};
var builder = WebApplication.CreateBuilder(webAppOptions);
我们还可以在调用WebApplicationOptions
之前从配置文件中读取EnvironmentName
并在WebApplication.CreateBuilder
中设置它
现在我们还可以在我们的开发机器上测试生产环境。 我们只需要切换到release
版本,我们就有了生产环境。
无需设置任何 ENVIRONMENT 变量。
这样做的好处还在于我们不会意外地创建在Development
环境下运行的发布版本。
您可以直接将ASPNETCORE_ENVIRONMENT
添加到您的 web.config 文件中:
<configuration>
<system.webServer>
<aspNetCore processPath="dotnet" arguments=".\MyProject.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</configuration>
什么可能对某些人有帮助:
对于 NET6 应用程序; 当我在本地运行已发布的应用程序时,将 ASPNETCORE_ENVIRONMENT 设置为 Development 似乎不起作用。
但是,当使用 IIS 复制到服务器时,它确实可以工作......所以可能是由于本地环境变量。
但是,由于 ASPNETCORE_ENVIRONMENT: Development 在服务器上加载了我的招摇文档。
我通过添加一个额外的 appsettings.Staging.json 文件解决了这个问题并发布:
dotnet publish -c Release -r win-x64 --no-self-contained /p:EnvironmentName=Staging
最后,我确保环境特定变量不在通用 appsettings.json 中,而仅在相应的 appsettings.{env}.json 文件中。
如前所述,您将这些行添加到发布配置文件中:
<PropertyGroup>
<EnvironmentName>Production</EnvironmentName>
</PropertyGroup>
然后在 .csproj 文件的条件部分使用此语法,例如:
<Exec WorkingDirectory="$(SpaRoot)" Command="npm build --prod" Condition="'$(EnvironmentName)' == 'Production'>
这也给我带来了麻烦。 我不想在我的代码中进行切换,而是希望从外部进行控制。 这是可能的。 您在上面的帖子中看到的选项有很多。 这就是我所做的。
设置代码
在 Program.cs 添加这个
var _configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables()
.Build();
第四句是json中的环境设置。第五句是通过环境变量在staging和prod中否决。
然后添加三个文件:
在 appsettings.json 中,我为每个环境放置了通用值。 IE 应用程序的名称。 在 appsettings.Development.json 中,我放置了连接字符串。 您也可以在暂存和生产中执行此操作。 出于安全原因,我做了不同的事情。
提示
上面的设置可以在开发模式下运行您的环境。 在 launchsettings.json 中,您可以将 AS.NETCORE_ENVIRONMENT 更改为 ie Staging 以查看其在测试/暂存模式下的工作方式。
部署
当我部署到 docker 时,我否决了环境设置以使代码在正确的环境中运行。 就是这样(这是从Nomad环境变量传给docker的方式,docker-compose格式会不一样,但是思路是一样的):
env {
ASPNETCORE_ENVIRONMENT = "Staging"
CONNECTIONSTRINGS__MYCS = "MyConnectionString"
}
当您以这种方式工作时,您将拥有干净的代码。
当我将启动设置从调试更改为暂存时,我希望加载正确的app<envronmentName>Settings.json
而不必记住将项目中的AS.NETCORE_ENVIRONMENT
设置从“开发”更改为“暂存”。 为此我修改Build条件编译符号如下;
[![在此处输入图片描述][1]][1]
然后在我的代码中使用;
string environmentName = "";
#if DEBUG
environmentName = "Development";
#elif STAGING
environmentName = "Staging";
#else
environmentName = "Production";
#endif
IConfigurationRoot config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false)
.AddJsonFile($"appsettings.{environmentName}.json", true)
.AddUserSecrets(Assembly.GetExecutingAssembly(), true)
.Build();
这会同步用于匹配所选启动配置的appSettings
文件。 [1]: https://i.stack.imgur.com/1XJlW.jpg
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.