【问题标题】:How to set ASPNETCORE_ENVIRONMENT to be considered for publishing an ASP.NET Core application如何设置 ASPNETCORE_ENVIRONMENT 以考虑发布 ASP.NET Core 应用程序
【发布时间】:2017-05-23 15:36:57
【问题描述】:

当我将 ASP.NET Core Web 应用程序发布到本地文件系统时,它总是采用 production-config 和值为“Production”的 ASPNETCORE_ENVIRONMENT 变量。

我必须如何以及在哪里设置 ASPNETCORE_ENVIRONMENT 变量的值,以便它不仅被考虑用于调试,而且也用于发布?我已经尝试了以下选项但没有成功:

  • 在 Windows 设置中
  • 在文件 .pubxml 文件中
  • 在文件 launchSettings.json
  • 在文件 project.json

【问题讨论】:

标签: c# asp.net-core environment-variables


【解决方案1】:

除了上面提到的选项,还有其他几个解决方案。

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 属性。

我们也可以在发布配置文件中添加&lt;EnvironmentName&gt; 属性。打开位于Properties/PublishProfiles/{profilename.pubxml} 的发布配置文件。这将在项目发布时在 web.config 中设置环境名称。更多详情here

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

3.使用dotnet publish的命令行选项

此外,我们可以将属性EnvironmentName 作为命令行选项传递给dotnet publish 命令。以下命令在 web.config 文件中包含环境变量 Development

dotnet publish -c Debug -r win-x64 /p:EnvironmentName=Development

【讨论】:

  • 据我所知,这似乎是最好的答案。为每个发布配置文件设置它的能力对我帮助很大。
  • 第三个选项对我有用。你知道 /p:EnvironmentName 选项是否在 dotnet 文档中的任何地方提及?
  • dotnet publish -c Debug -r win-x64 /p:EnvironmentName=Development 正是我想要的。谢谢!
  • 如果您的环境在发布时没有重新加载,请重新加载项目。
  • 我喜欢通过上面的dotnet publish 执行此操作的想法,但这只是将其添加到 web.config 文件中,显然我的 aspnet core 3.1 应用程序默认不会读取。
【解决方案2】:

选项1:

在 Windows 中设置 ASPNETCORE_ENVIRONMENT 环境变量:

  • 命令行 - setx ASPNETCORE_ENVIRONMENT "Development"

  • PowerShell - $Env:ASPNETCORE_ENVIRONMENT = "Development"

其他操作系统请参考Use multiple environments in 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>

【讨论】:

  • 这两个都是糟糕的选择。 1)为整个操作系统设置它,我希望在 IIS 中的每个站点都设置它。 2) AspNet Core 不支持 web.config 转换。您如何建议修改 web.config 以进行部署?
  • 一旦你遇到更好的选择......请在这里分享:)
  • ASPNETCORE_ENVIRONMENT 的想法是你可以使用 docker 并且只有一个 docker 运行一个 IIS。而另一个我认为如果你使用 Web.Config 的 ASP 网络核心,你应该手动进行转换。
  • 这种配置设计看起来很乱。
  • 您可以在多个环境的发布配置文件中覆盖它。
【解决方案3】:

在 Visual Studio IDE 中进行设置的简单方法。

菜单项目属性调试环境变量

【讨论】:

  • 但是你需要记住每次你需要发布到不同的环境时改变这个。
  • 这不正确。这仅在运行 IDE 时有效。将其存储在作为 Visual Studio 的东西的 launchsettings.json 文件中。不适用于部署。
【解决方案4】:

这是我们可以在运行时设置它的方式:

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();
}

【讨论】:

  • 不知道为什么这被否决了,因为它是唯一对我有用的东西。
  • 由于代码中的硬编码值,它很可能被否决了。
  • 最快的测试,但我同意这不是我希望看到的长期签入代码。
  • 虽然这是硬编码的,但我认为这是最简单的方法。
  • 我的首选方法,我结合DEBUG使用它来设置正确的值。
【解决方案5】:

您应该关注instructions provided in the documentation,使用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 属性中指定的进程 在一个或多个 environmentVariable 的子元素中 aspNetCore 元素下的 environmentVariables 集合元素。 本节中设置的环境变量优先于系统 进程的环境变量。

【讨论】:

  • 如何在 .net 核心控制台应用程序中设置它?
  • 通过 Windows 的环境变量对话框设置它们。
  • 但是有没有办法在项目而不是操作系统中设置它?
  • 不适用于我知道的 .NET Core 中的控制台应用程序......不 - 也许是这个 - stackoverflow.com/a/46445432/2410379?
【解决方案6】:
  1. 创建您的 appsettings.*.json 文件。 (示例:appsettings.Development.jsonappsettings.Staging.jsonappsettings.Production.json

  2. 将变量添加到这些文件中。

  3. 像往常一样为每个环境创建单独的发布配置文件。

  4. 打开 PublishProfiles/Development.pubxml 文件(命名将基于您命名的发布配置文件)。

  5. 只需将标签添加到 PublishProfile 以设置 EnvironmentName 变量,其余的由 appsettings.*.json 文件命名约定完成.

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

参考:Visual Studio publish profiles (.pubxml) for ASP.NET Core app deployment

请参阅“设置环境”部分。

【讨论】:

  • 我已经这样做了,虽然它在已发布的 web.config 文件中正确设置了环境,但我正在努力处理 appsettings.*.json 文件。我有 appsettings.Staging.json 但是当我发布它时它仍然是 appsettings.Staging.json 并且没有变成 appsettings.json 并且网站无法工作(不读取该文件)
  • @Paul 实际上 dotnetcore 将读取并加载 appsettings.json(如果格式不正确或根本不存在,则会失败),并且还会尝试读取 appsettings.{currentEnv}。 json(如果格式不正确或不存在,则不会失败)。这是 Program.cs 文件中“CreateWebHostBuilder”方法中对“WebHost.CreateDefaultBuilder()”的调用,默认情况下会自动加载这些文件。
【解决方案7】:

这个变量可以保存在 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 中。

【讨论】:

    【解决方案8】:

    使用最新版本的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

    【讨论】:

    • 能否详细说明you can just set this msbuild property $(EnvironmentName) and publish或提供参考?
    • 如何在 .net 核心控制台应用程序中设置它?
    【解决方案9】:

    而不是硬连线开发设置,将其添加到您的.csproj

    <!-- Adds EnvironmentName variable during publish -->
    <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
        <EnvironmentName>Development</EnvironmentName>
    </PropertyGroup>
    
    <PropertyGroup Condition="'$(Configuration)' == 'Release'">
        <EnvironmentName>Production</EnvironmentName>
    </PropertyGroup>
    

    【讨论】:

    • 我知道这与原始问题无关,但如果您使用 web 部署,这种方法非常好。当您使用开发和登台环境时,这些实例也可以在同一个机器上轻松运行,而无需共享 ASPNETCORE_ENVIRONMENT 环境变量。
    【解决方案10】:

    一个简单的解决方案

    我使用当前目录来判断当前环境,然后翻转连接字符串和环境变量。只要您的站点文件夹有一个命名约定,例如 testbetasandbox,这将非常有效。

    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();
    }
    

    【讨论】:

      【解决方案11】:

      如果您在 Windows、Linux 或 Mac 上使用 Rider IDE(来自 JetBrains):

      • 点击添加配置
      • 在模式窗口中,单击位于左侧列中的Add New...
      • 选择 .NET 项目(模板取决于您的项目类型)
      • 环境变量字段中,点击右侧的文档图标;
      • 在新窗口中点击+新建环境变量,输入key/value ASPNETCORE_ENVIRONMENT/Development;
      • 单击窗口右下方的确定
      • 点击窗口右下方的应用

      Rider 已包含您项目的启动设置,并将其设置为您的项目调试和运行的默认设置。

      【讨论】:

        【解决方案12】:

        我不得不手动将这段代码添加到我的 main 方法中。这将使环境基于 Azure 的应用设置

        static async Task Main(string[] args)
        {
           ...
           //set the environment variable based on App Settings
           var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
           builder.UseEnvironment(environment);
        

        【讨论】:

          【解决方案13】:

          为了能够为每个站点设置环境,我们在项目中使用的另一个选项是向项目中添加一个 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 ActionContentCopy ActionCopy 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"
          

          这样我们可以有多个版本,都使用相同的工件,但部署为不同的环境。

          【讨论】:

            【解决方案14】:

            通过直接在 Azure 平台上设置此变量(如果您使用它),我发现它对我有用。

            只需选择您的 Web 应用程序 → 配置应用程序设置 并添加变量及其值。然后按保存按钮。

            【讨论】:

              猜你喜欢
              • 2019-08-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-07-16
              • 1970-01-01
              • 2023-01-24
              • 2017-03-06
              相关资源
              最近更新 更多