阅读这两个问题/答案,我能够在 IIS 8.5 服务器上运行 Asp.net 5 应用程序。
Asp.net vNext early beta publish to IIS in windows server
How to configure an MVC6 app to work on IIS?
问题是,即使在 IIS 上运行,Web 应用程序仍在使用值为 Development
的 env.EnvironmentName
。
另外,我想在同一台服务器上运行同一个 Web 的两个版本(Staging、Production),所以我需要一种方法来分别为每个 Web 设置变量。
这个怎么做?
Properties\launchSettings.json
在 Visual Studio 中模拟另一个环境进行调试。
这个答案最初是为 ASP.NET Core RC1 编写的。在 RC2 中,ASP.NET Core 从通用 httpPlafrom 处理程序移至特定于 aspnetCore 的处理程序。请注意,第 3 步取决于您使用的 ASP.NET Core 版本。
结果表明可以设置 ASP.NET Core 项目的环境变量,而无需为用户设置环境变量或创建多个命令条目。
转到 IIS 中的应用程序并选择配置编辑器。选择 Configuration Editor 在 Section 组合框中选择 system.webServer/aspNetCore(RC2 和 RTM)或 system.webServer/httpPlatform (RC1) 在 From 组合框中选择 Applicationhost.config ...。右键单击 enviromentVariables 元素,选择“environmentVariables”元素,然后选择 Edit Items。设置环境变量。关闭窗口并单击应用。完毕
这样您就不必为您的池创建特殊用户或在 project.json
中创建额外的命令条目。此外,为每个环境添加特殊命令会破坏“一次构建,多次部署”,因为您必须为每个环境单独调用 dnu publish
,而不是发布一次并多次部署生成的工件。
感谢 Mark G 和 tredder,为 RC2 和 RTM 更新。
使用
<configuration>
<system.webServer>
<aspNetCore .....>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</configuration>
或者为避免在覆盖 web.config 时丢失此设置,对 applicationHost.config 进行类似更改,指定站点位置,如 @NickAb 建议的那样。
<location path="staging.site.com">
<system.webServer>
<aspNetCore>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
<location path="production.site.com">
<system.webServer>
<aspNetCore>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
Target configuration object '/system.webServer/aspNetCore/environmentVariables/environmentVariable is not found ...
通常设置一些变量我会写这样的内容:Set-WebConfigurationProperty -PSPath IIS:\ -location example.com -filter /system.webServer/aspNetCore/environmentVariables/environmentVariable -name ASPNETCORE_ENVIRONMENT -value Staging
我错过了什么?
appcmd
。
Set-WebConfigurationProperty -PSPath IIS:\ -Location example.com -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value @{ Name = 'ASPNETCORE_ENVIRONMENT'; Value = 'Staging' }
您也可以使用以下命令将所需的 ASPNETCORE_ENVIRONMENT
作为参数传入 dotnet publish 命令:
/p:EnvironmentName=Staging
例如:
dotnet publish /p:Configuration=Release /p:EnvironmentName=Staging
这将使用为您的项目指定的正确环境生成 web.config:
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
</environmentVariables>
编辑:从 RC2 和 RTM 版本开始,此建议已过时。我发现在发行版中完成此操作的最佳方法是在 IIS 中为每个环境编辑以下 web.config 部分:
system.webServer/aspNetCore
:
编辑 environmentVariable 条目并添加环境变量设置:
ASPNETCORE_ENVIRONMENT
:< Your environment name >
作为 drpdrp 方法的替代方案,您可以执行以下操作:
在您的 project.json 中,添加将 ASPNET_ENV 变量直接传递给 Kestrel 的命令: "commands": { "Development": "Microsoft.AspNet.Server.Kestrel --ASPNET_ENV Development", "Staging": "Microsoft.AspNet.Server .Kestrel --ASPNET_ENV 暂存”,“生产”:“Microsoft.AspNet.Server.Kestrel --ASPNET_ENV 生产”}
发布时,使用 --iis-command 选项指定环境: dnu publish --configuration Debug --iis-command Staging --out "outputdir" --runtime dnx-clr-win-x86-1.0.0-rc1 -更新1
我发现这种方法比创建额外的 IIS 用户更具侵入性。
除了上面提到的选项之外,还有一些其他解决方案可以很好地用于自动化部署或需要较少的配置更改。
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
。更多详情here
2. 在发布配置文件中添加 EnvironmentName 属性。
我们也可以在发布配置文件中添加 <EnvironmentName>
属性。打开位于 Properties/PublishProfiles/{profilename.pubxml}
的发布配置文件,这将在发布项目时在 web.config 中设置环境名称。更多详情here
<PropertyGroup>
<EnvironmentName>Development</EnvironmentName>
</PropertyGroup>
3. 使用 dotnet publish 的命令行选项
另外,我们可以将属性 EnvironmentName
作为命令行选项传递给 dotnet publish
命令。以下命令会将环境变量作为 Development
包含在 web.config 文件中。
dotnet publish -c Debug -r win-x64 /p:EnvironmentName=Development
我的 Web 应用程序(生产、暂存、测试)托管在 IIS Web 服务器上。所以不可能依赖 ASPNETCORE_ENVIRONMENT 操作员的系统环境变量,因为将其设置为特定值(例如 STAGING)会影响其他应用程序。
作为解决方法,我在我的 visualstudio 解决方案中定义了一个自定义文件 (envsettings.json):
https://i.stack.imgur.com/RdNfP.png
内容如下:
{
// Possible string values reported below. When empty it use ENV variable value or Visual Studio setting.
// - Production
// - Staging
// - Test
// - Development
"ASPNETCORE_ENVIRONMENT": ""
}
然后,根据我的应用程序类型(生产、暂存或测试)我相应地设置此文件:假设我正在部署 TEST 应用程序,我将拥有:
"ASPNETCORE_ENVIRONMENT": "Test"
之后,在 Program.cs 文件中检索此值,然后设置 webHostBuilder 的环境:
public class Program
{
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 enviromentValue = envSettings["ASPNETCORE_ENVIRONMENT"].ToString();
var webHostBuilder = new WebHostBuilder()
.UseKestrel()
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseContentRoot(currentDirectoryPath)
.UseIISIntegration()
.UseStartup<Startup>();
// If none is set it use Operative System hosting enviroment
if (!string.IsNullOrWhiteSpace(enviromentValue))
{
webHostBuilder.UseEnvironment(enviromentValue);
}
var host = webHostBuilder.Build();
host.Run();
}
}
请记住在 publishOptions (project.json) 中包含 envsettings.json:
"publishOptions":
{
"include":
[
"wwwroot",
"Views",
"Areas/**/Views",
"envsettings.json",
"appsettings.json",
"appsettings*.json",
"web.config"
]
},
这个解决方案让我可以自由地将 ASP.NET CORE 应用程序托管在同一个 IIS 上,独立于环境变量值。
经过广泛的谷歌搜索,我找到了一个可行的解决方案,它包括两个步骤。
第一步是将系统范围的环境变量 ASPNET_ENV 设置为生产并重新启动 Windows 服务器。在此之后,所有 Web 应用程序都将值“生产”作为 EnvironmentName。
第二步(为登台网络启用值“登台”)相当难以正常工作,但这里是:
在服务器上创建新的 windows 用户,例如 StagingPool。对于此用户,创建新的用户变量 ASPNETCORE_ENVIRONMENT 值“Staging”(您可以通过以该用户身份登录或通过 regedit 来完成)在 IIS 管理器中以管理员身份返回,找到正在运行 Staging Web 的应用程序池并在“高级”中设置将 Identity 设置为用户 StagingPool。还将 Load User Profile 设置为 true,以便加载环境变量。 <-非常重要!确保 StagingPool 有权访问 Web 文件夹以及停止和启动应用程序池。
现在,Staging web 应该将 EnvironmentName 设置为“Staging”。
更新:在 Windows 7+ there is a command 中,也可以为指定用户从 CMD 提示符设置环境变量。这会输出帮助和示例:
>setx /?
只需将
<PropertyGroup>
<EnvironmentName>Development</EnvironmentName>
</PropertyGroup>
该信息被复制到 web.config。 (不要手动设置 web.config,因为它会被覆盖。)
来源:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments
与其他答案类似,我想确保我的 ASP.NET Core 2.1 环境设置在部署中保持不变,但也仅适用于特定站点。
根据 Microsoft 的文档,可以在 IIS 10 中使用以下 PowerShell 命令在应用程序池上设置环境变量:
$appPoolName = "AppPool"
$envName = "Development"
cd "$env:SystemRoot\system32\inetsrv"
.\appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='$appPoolName'].environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='$envName']" /commit:apphost
不幸的是,我仍然必须使用 IIS 8.5,并认为我不走运。但是,仍然可以运行一个简单的 PowerShell 脚本来为 ASPNETCORE_ENVIRONMENT 设置特定于站点的环境变量值:
Import-Module -Name WebAdministration
$siteName = "Site"
$envName = "Development"
Set-WebConfigurationProperty -PSPath IIS:\ -Location $siteName -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value @{ Name = 'ASPNETCORE_ENVIRONMENT'; Value = $envName }
要扩展@tredder 的答案,您可以使用 appcmd
更改 environmentVariables
分期
%windir%\system32\inetsrv\appcmd set config "staging.example.com" /section:system.webServer/aspNetCore /+environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='Staging'] /commit:APPHOST
生产
%windir%\system32\inetsrv\appcmd set config "example.com" /section:system.webServer/aspNetCore /+environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='Production'] /commit:APPHOST
您需要在一个地方了解的内容:
对于覆盖任何配置设置的环境变量,它们必须以 ASPNETCORE_ 为前缀。
如果要匹配 JSON 配置中的子节点,请使用 : 作为分隔符。如果平台不允许在环境变量键中使用冒号,请改用 __。
您希望您的设置在 ApplicationHost.config 中结束。使用 IIS 配置编辑器将导致您的输入被写入应用程序的 Web.config - 并且将被下一次部署覆盖!
对于修改 ApplicationHost.config,您需要使用 appcmd.exe 来确保您的修改是一致的。示例:%systemroot%\system32\inetsrv\appcmd.exe set config "Default Web Site/MyVirtualDir" -section:system.webServer/aspNetCore /+"environmentVariables.[name='ASPNETCORE_AWS:Region',value='eu-central -1']" /提交:网站
不是 URL 安全的字符可以转义为 Unicode,例如 %u007b 用于左花括号。
列出您当前的设置(结合 Web.config 中的值):%systemroot%\system32\inetsrv\appcmd.exe list config "Default Web Site/MyVirtualDir" -section:system.webServer/aspNetCore
如果您多次运行命令为同一个密钥设置配置密钥,它将被多次添加!要删除现有值,请使用 %systemroot%\system32\inetsrv\appcmd.exe set config "Default Web Site/MyVirtualDir" -section:system.webServer/aspNetCore /-"environmentVariables.[name='ASPNETCORE_MyKey',value ='要删除的值']" /commit:site.
/commit:site
,更改写入 web.config,为了将它们保存在 ApplicationHost.config
中,应该使用 /commit:apphost
-section:system.webServer/aspNetCore /-"environmentVariables.
(用减号删除环境变量)在 Azure 发布管道期间无法执行。错误是 hresult:80070032, message:Command execution failed
。但是 clear config "Default Web Site/$(webSiteName)" -section:system.webServer/aspNetCore /commit:site
工作正常。它清除了网站的整个 aspNetCore 部分,但这不是问题,因为它在发布期间已参数化。
如果您有多个不同的应用程序位于 IIS 上的虚拟目录中,则带有编辑 applicationHost.config 的@tredder 解决方案是可行的。
我的情况是:
我确实有API项目和APP项目,在同一个域下,放在不同的虚拟目录中
根页面 XXX 似乎没有将 ASPNETCORE_ENVIRONMENT 变量传播到其虚拟目录中的子级,并且...
...我无法按照@NickAb 的描述设置虚拟目录中的变量(在配置编辑器中保存更改期间出现错误请求不受支持。(HRESULT 异常:0x80070032)):
进入 applicationHost.config 并像这样手动创建节点:
并重新启动 IIS 完成了这项工作。
我知道已经给出了很多答案,但就我而言,我在项目中添加了 web.{Environment}.config 版本,并且在为特定环境发布时,值被替换。
例如,对于暂存 (web.Staging.config)
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<location>
<system.webServer>
<aspNetCore>
<environmentVariables xdt:Transform="InsertIfMissing">
<environmentVariable name="ASPNETCORE_ENVIRONMENT"
value="Staging"
xdt:Locator="Match(name)"
xdt:Transform="InsertIfMissing" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>
对于发布或生产,我会这样做(web.Release.config)
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<location>
<system.webServer>
<aspNetCore>
<environmentVariables xdt:Transform="InsertIfMissing">
<environmentVariable name="ASPNETCORE_ENVIRONMENT"
value="Release"
xdt:Locator="Match(name)"
xdt:Transform="InsertIfMissing" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>
然后在发布时我会选择或设置环境名称。这将替换最终 web.config 文件中环境的值。
对于那些希望在 azure devops 管道中实现这一点的人,可以通过添加 PowerShell on target machines 任务并运行以下脚本来实现:
$envVariables = (
@{name='VARIABLE1';value='Value1'},
@{name='VARIABLE2';value='Value2'}
)
Set-WebConfigurationProperty -PSPath IIS:\ -Location $('mySite') -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value $envVariables
要获取有关错误的详细信息,我必须为相应的应用程序池 system.applicationHost/applicationPools
添加 ASPNETCORE_ENVIRONMENT
环境变量。
注意:在我的例子中,Web 应用程序是托管在 IIS 10
上的 ASP.NET Core 2
Web 应用程序。它可以通过 IIS Manager
中的 Configuration Editor
完成(请参阅 Editing Collections with Configuration Editor 以了解在 IIS Manager
中的何处可以找到此编辑器)。
我已经创建了一个存储库,用于在 Web.config 中使用环境配置发布 IIS。
https://github.com/expressiveco/AspnetCoreWebConfigForEnvironment
设置 将 .csproj 和 .user.csproj 文件中的部分放入您的项目文件中。获取 MyAspNetEnvironment.props、web.development.config 和 web.production.config 文件。
将 .csproj 和 .user.csproj 文件中的部分获取到您的项目文件中。
获取 MyAspNetEnvironment.props、web.development.config 和 web.production.config 文件。
配置 相应地更改 user.csproj 中 ASPNETCORE_ENVIRONMENT 属性的值。
相应地更改 user.csproj 中 ASPNETCORE_ENVIRONMENT 属性的值。
我已经修改了@Christian Del Bianco 给出的答案。我将 .net core 2 和更高版本的流程更改为 project.json 文件现在是绝对的。
首先,在根目录下创建 appsettings.json 文件。 with the content { // 下面报告的可能的字符串值。为空时,它使用 ENV 变量值或 Visual Studio 设置。 // - 生产 // - 暂存 // - 测试 // - 开发 "ASPNETCORE_ENVIRONMENT": "Development" } 然后使用必要的配置创建另外两个设置文件 appsettings.Development.json 和 appsettings.Production.json。在 Program.cs 文件中添加必要的代码来设置环境。公共类程序 { public static void Main(string[] args) { var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); ***var currentDirectoryPath = Directory.GetCurrentDirectory(); var envSettingsPath = Path.Combine(currentDirectoryPath, "envsettings.json"); var envSettings = JObject.Parse(File.ReadAllText(envSettingsPath)); var enviromentValue = envSettings["ASPNETCORE_ENVIRONMENT"].ToString();*** try { ***CreateWebHostBuilder(args, enviromentValue).Build().Run();*** } catch (Exception ex) { //NLog : 捕捉设置错误 logger.Error(ex, "Stopped program because of setup related exception");扔; } 最后 { NLog.LogManager.Shutdown(); } } public static IWebHostBuilder CreateWebHostBuilder(string[] args, string enviromentValue) => WebHost.CreateDefaultBuilder(args) .UseStartup
system.webServer/aspNetCore
。