ChatGPT解决这个技术问题 Extra ChatGPT

如何设置 ASPNETCORE_ENVIRONMENT 以考虑发布 ASP.NET Core 应用程序

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

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

在 Windows 设置中

在文件 .pubxml 文件中

在文件launchSettings.json

在文件 project.json


P
Peter Mortensen

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

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 命令。以下命令在 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 应用程序默认情况下不会读取该文件。
P
Peter Mortensen

选项1:

在 Windows 中设置 ASPNETCORE_ENVIRONMENT 环境变量:

命令行 - setx ASPNETCORE_ENVIRONMENT "开发"

PowerShell - $Env:ASPNETCORE_ENVIRONMENT = "开发"

对于其他操作系统,请参阅 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 网络核心,你应该手动进行转换。
这种配置设计看起来很乱。
您可以在多个环境的发布配置文件中覆盖它。
P
Peter Mortensen

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

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

https://i.stack.imgur.com/HF7M9.png


但是,您需要记住每次需要发布到不同的环境时更改此设置。
这是不正确的。这仅在运行 IDE 时有效。将其存储在作为 Visual Studio 的东西的 launchsettings.json 文件中。不适用于部署。
P
Peter Mortensen

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

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 结合使用来设置正确的值。
P
Peter Mortensen

创建您的 appsettings.*.json 文件。 (示例:appsettings.Development.json、appsettings.Staging.json 和 appsettings.Production.json)将变量添加到这些文件中。像往常一样,为每个环境创建一个单独的发布配置文件。打开 PublishProfiles/Development.pubxml 文件(命名将基于您命名的发布配置文件)。只需将标签添加到 PublishProfile 以设置 EnvironmentName 变量,剩下的工作由 appsettings.*.json 文件命名约定完成。 开发

参考: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()”的调用,默认情况下会自动加载这些文件。
不使用 dotnet 6:/ 我添加了道具,但 env 始终是生产环境。
D
David Pine

您应该遵循 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 属性中指定的进程指定环境变量,方法是在 aspNetCore 元素下的 environmentVariables 集合元素的一个或多个 environmentVariable 子元素中指定它们。本节中设置的环境变量优先于进程的系统环境变量。


我将如何在 .net 核心控制台应用程序中设置它?
通过 Windows 的环境变量对话框设置它们。
但是有没有办法在项目而不是操作系统中设置它?
不适用于我知道的 .NET Core 中的控制台应用程序......不 - 也许这个 - stackoverflow.com/a/46445432/2410379
P
Peter Mortensen

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


P
Peter Mortensen

使用最新版本的 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 核心控制台应用程序中设置它?
P
Peter Mortensen

而不是硬连线开发设置,将其添加到您的 .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 环境变量。
P
Peter Mortensen

一个简单的解决方案

我使用当前目录来确定当前环境,然后翻转连接字符串和环境变量。只要您有站点文件夹的命名约定(例如测试、测试版和沙盒),这将非常有效。

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

P
Peter Mortensen

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

点击添加配置;

在模式窗口中,单击位于左栏中的 Add New...。

选择 .NET 项目(模板取决于您的项目类型)

在环境变量字段中,单击右侧的文档图标;

在新窗口中,点击+创建一个新的环境变量,你将输入key/value ASPNETCORE_ENVIRONMENT/Development;

单击窗口右下方的确定。

单击窗口右下角的应用。

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

https://i.stack.imgur.com/BjBDV.png


D
Div

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

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

P
Peter Mortensen

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

此文件的构建操作是内容,复制操作是 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"

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


P
Peter Mortensen

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

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


C
Charles

对于 .NET 6,我发现这是最好的解决方案:

var webAppOptions = new WebApplicationOptions()
{   
    Args = args,

    #if DEBUG
        EnvironmentName = Environments.Development,
    #else
        EnvironmentName = Environments.Production,
    #endif

};

var builder = WebApplication.CreateBuilder(webAppOptions);

我们还可以从配置文件中读取 EnvironmentName 并将其设置在 WebApplicationOptions 中,然后再调用 WebApplication.CreateBuilder

现在我们还可以在我们的开发机器上测试生产环境。我们只需切换到 release 构建,我们就有了生产环境。

无需设置任何 ENVIRONMENT 变量。

这样做的好处还在于我们不会意外创建在 Development 环境下运行的发布版本。


Z
Zahil John

过去几天我一直在寻找这个问题的答案,以了解如何通过部署到 Azure 应用服务的 Azure DevOps 发布管道来实现这一点。这是我如何实现它的 - 希望这会对你有所帮助。

在 Azure App Service 部署任务 > 在应用程序和配置设置中设置此值:-ASPNETCORE_ENVIRONMENT ""

https://i.stack.imgur.com/vEWIt.png


C
Chris W

您可以直接将 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>

R
Robin

什么可能对某些人有帮助:

对于 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 文件中。


M
MAZEN ALDUBAI

如前所述,您将这些行添加到发布配置文件中:

<PropertyGroup>
    <EnvironmentName>Production</EnvironmentName>
</PropertyGroup>

然后在 .csproj 文件的条件部分使用此语法,例如:

<Exec WorkingDirectory="$(SpaRoot)" Command="npm build --prod" Condition="'$(EnvironmentName)' == 'Production'>