ChatGPT解决这个技术问题 Extra ChatGPT

发布到 IIS,设置环境变量

阅读这两个问题/答案,我能够在 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 应用程序仍在使用值为 Developmentenv.EnvironmentName

另外,我想在同一台服务器上运行同一个 Web 的两个版本(Staging、Production),所以我需要一种方法来分别为每个 Web 设置变量。

这个怎么做?

一个通常具有三个网络环境开发、登台和生产。 Web 服务器与环境合一。因此,为服务器设置系统环境变量通常不是真正的限制。仍然可以使用 Properties\launchSettings.json 在 Visual Studio 中模拟另一个环境进行调试。

J
Johnny Wu

这个答案最初是为 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 更新。


对于第 3 步,我改用 system.webServer/aspNetCore
通过配置编辑器添加的设置不会在下一次部署中消失吗?
@brad-gardner 如果对 Applicationhost.config 而不是 web.config 进行了更改,那么更改将在部署之间保持不变。
@the-red-pea 请注意,在您链接的说明中,web.config 已更改,而不是 applicationhost.config。对特定 IIS 服务器上的 web.config 所做的任何更改都将在下次部署时丢失。对 applicationhost.config 的更改会在部署之间保留在特定的 IIS 服务器上。
适用于 Asp.Net Core 2.0
T
Trevor Daniels

使用 下的 部分更新 web.config

<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>

这与您的 web.config 是项目的一部分并在 VCS 中进行版本控制的方式不同。如果您有多个环境,例如 prod、staging、dev,那么您将需要一些方法来为每个环境转换 web.config。在 IIS 中更改 ApplicationHost.config 仅影响此 IIS。这样您就可以在 VCS 中拥有单个 web.config 和特定于 IIS 的环境变量,这些变量会覆盖 web.config 变量。可以使用 PowerShell iis.net/learn/manage/powershell/… 以编程方式编辑 ApplicationHost.config
感谢@NickAb,这避免了每次部署都必须更新 web.config。我已经更新了我的答案。
我在从 powershell 执行此操作时遇到问题我不断收到 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
@Christian,看看这个答案:stackoverflow.com/a/50869935/33533 环境变量名称和值放在一个哈希表中,所以从你的例子来看它是 Set-WebConfigurationProperty -PSPath IIS:\ -Location example.com -Filter /system.webServer/aspNetCore/environmentVariables -Name . -Value @{ Name = 'ASPNETCORE_ENVIRONMENT'; Value = 'Staging' }
S
Stephen Rauch

您也可以使用以下命令将所需的 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>

C
CodeNotFound

编辑:从 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 用户更具侵入性。


如果您通过 Visual Studio 的 msdeploy 发布。然后,您可以将 Staging 放入您的 .pubxml 文件中,即使您无法在发布 UI 中指定它,它也会使用指定的 IIS 命令进行部署。
@DeanNorth - 这是金!像冠军一样工作!感谢分享!
A
Abhinav Galodha

除了上面提到的选项之外,还有一些其他解决方案可以很好地用于自动化部署或需要较少的配置更改。

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


这似乎在 .net core 3.1 中不起作用,它仍然没有为我设置。
@rouge39nin - 我对其进行了测试,它在 .net core 3.1 中运行。您能否提供有关您尝试过的内容以及托管方式的更多详细信息?
C
Christian Del Bianco

我的 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 上,独立于环境变量值。


非常好,我建议的唯一更改是 swap var currentDirectoryPath = Directory.GetCurrentDirectory();对于 var currentDirectoryPath = PlatformServices.Default.Application.ApplicationBasePath;这是获取当前目录的更安全的方法。
当您必须创建另一层配置来管理框架的配置时,开箱即用的体验真是太棒了
“因此不可能依赖 ASPNETCORE_ENVIRONMENT 操作员的系统环境变量”的断言可能不正确。每个应用程序都有自己的池,因此没有什么能阻止您为每个应用程序设置环境。
c
cvbarros

经过广泛的谷歌搜索,我找到了一个可行的解决方案,它包括两个步骤。

第一步是将系统范围的环境变量 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 /?

似乎在 ASP.NET 5 RC1 中,环境变量已更改为 Hosting:Environment。
当我们将其部署到 Azure Web App 时,如何将“加载用户配置文件”设置为 true?
@PunitGanshani 据我了解,Azure 门户网站中有一个“应用程序设置”部分,您可以在其中设置环境键/值对:azure.microsoft.com/en-us/documentation/articles/…
@GradyWerner 对于 RC2,他们正在将其(截至目前)更改为 ASPNET_ENVIRONMENT ;-)
@b.pell 现在看来是 ASPNETCORE_ENVIRONMENT :)
M
MarredCheese

只需将 添加到您的发布配置文件中:

<PropertyGroup>
  <EnvironmentName>Development</EnvironmentName>
</PropertyGroup>

该信息被复制到 web.config。 (不要手动设置 web.config,因为它会被覆盖。)

来源:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments


d
dasch88

与其他答案类似,我想确保我的 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 }

C
Christian

要扩展@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


这是在没有安装 IIS 的构建服务器上使用 Powershell 完成相同操作的方法。 gist.github.com/markarnott/c4aec1fc544fe89e2bd21f3f00d78933
指定“staging.example.com”或“example.com”只会将该变量应用于这些特定网站。省略将为服务器上的所有网站创建一个全局变量。
r
realMarkusSchmidt

您需要在一个地方了解的内容:

对于覆盖任何配置设置的环境变量,它们必须以 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 部分,但这不是问题,因为它在发布期间已参数化。
B
Bartosz Lenar

如果您有多个不同的应用程序位于 IIS 上的虚拟目录中,则带有编辑 applicationHost.config 的@tredder 解决方案是可行的。

我的情况是:

我确实有API项目和APP项目,在同一个域下,放在不同的虚拟目录中

根页面 XXX 似乎没有将 ASPNETCORE_ENVIRONMENT 变量传播到其虚拟目录中的子级,并且...

...我无法按照@NickAb 的描述设置虚拟目录中的变量(在配置编辑器中保存更改期间出现错误请求不受支持。(HRESULT 异常:0x80070032)):

进入 applicationHost.config 并像这样手动创建节点:

并重新启动 IIS 完成了这项工作。


I
Ismail Umar

我知道已经给出了很多答案,但就我而言,我在项目中添加了 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 文件中环境的值。


s
sjokkogutten

对于那些希望在 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

这正是我一直在寻找的。谢谢你。
D
Dmitry Pavlov

要获取有关错误的详细信息,我必须为相应的应用程序池 system.applicationHost/applicationPools 添加 ASPNETCORE_ENVIRONMENT 环境变量。

注意:在我的例子中,Web 应用程序是托管在 IIS 10 上的 ASP.NET Core 2 Web 应用程序。它可以通过 IIS Manager 中的 Configuration Editor 完成(请参阅 Editing Collections with Configuration Editor 以了解在 IIS Manager 中的何处可以找到此编辑器)。


l
lockedscope

我已经创建了一个存储库,用于在 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 属性的值。


这似乎没有为问题提供quality answer。请编辑您的答案,添加此解决方案的整体详细信息,或者将其删除并将其作为对问题的评论发布。谢谢!
M
Md. Nazrul Islam

我已经修改了@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() .ConfigureLogging(logging => { logging.ClearProviders(); logging.SetMinimumLevel(Microsoft.Extensions) .Logging.LogLevel.Trace); }) .UseNLog() ***.UseEnvironment(enviromentValue);*** } 将 envsettings.json 添加到您的 .csproj 文件以复制到已发布的目录。 现在只需在 envsettings.json 文件中更改 ASPNETCORE_ENVIRONMENT 并发布即可。