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