繁体   English   中英

如何设置要考虑发布 ASP.NET Core 应用程序的 AS.NETCORE_ENVIRONMENT

[英]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 变量的值,以便它不仅用于调试,而且用于发布 我已经尝试了以下选项但没有成功:

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

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

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>

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

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

在此处输入图像描述

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

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

参考: 用于 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>

一个简单的解决方案

我使用当前目录来确定当前环境,然后翻转连接字符串和环境变量。 只要您有站点文件夹的命名约定,例如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();
}

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

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

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

环境设置结束和默认

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

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

我不得不手动将这段代码添加到我的主要方法中。 这将基于 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环境下运行的发布版本。

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

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

在此处输入图像描述

您可以直接将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中否决。

然后添加三个文件:

  • 应用程序设置.json
  • appsettings.Development.json
  • appsettings.Staging.json
  • appsettings.Production.json

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM