ASP.NET and ASP NETCORE multi environment configuration comparison

preface

Multi environment configuration should be familiar. The most common environments are Debug and Release. For example, the following figure shows a new ASP Net project, the deployment of configuration file is composed of three files

Some developers have never understood the web Debug. Config and web Release. Config, always a web The config file is changed to switch different configurations, but anyone who pursues it can't stand this suffering.

asp.net

Double click to open web Debug. Config and web Release. Config any one, look at the contents.

Web.Debug.config
<?xml version="1.0" encoding="utf-8"?>

<!-- About use Web.config For more information on conversion, please visit https://go.microsoft.com/fwlink/?LinkId=301874 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <!--
    In the following example“ SetAttributes"The conversion will change
    "connectionString"Value of, only in“ Match"Locator found value“ MyDB"of
    Characteristics“ name"When using“ ReleaseSQLServer". 

    <connectionStrings>
      <add name="MyDB"
        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
        xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
    </connectionStrings>
  -->
  <system.web>
    <!--
      In the following example,"Replace" Conversion will replace Web.config Document
      whole <customErrors> Festival.
      Please note that due to <system.web> There is only one under the node
       customErrors Section, so there is no need to use "xdt:Locator" Properties.

      <customErrors defaultRedirect="GenericError.htm"
        mode="RemoteOnly" xdt:Transform="Replace">
        <error statusCode="500" redirect="InternalError.htm"/>
      </customErrors>
    -->
  </system.web>
</configuration>

In order for us to use it, Microsoft not only gives examples, but also adds detailed comments. After reading the comments and examples, we should probably know how to configure and cover the web Config.
The following shows how to configure the most commonly used appSettings

  <!--Web.config development environment -->
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    
    <add key="MyKey" value="Myvalue" />
  </appSettings>
  <!--Web.Release.config production environment -->
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    
    <add key="MyKey" value="Releasvalue" xdt:Transform="Replace" xdt:Locator="Match(key)" />
  </appSettings>

After such configuration, the value of MyKey read during local development is Myvalue, and the value is Releasvalue when publishing the production environment.
According to the above configuration, try the effect of local publishing program.

After publishing successfully, open the web generated after publishing Config file, we found that web The corresponding value in config has been replaced, so that the development and production configurations are configured in different files, and there is no need to frequently modify the configuration file and switch the configuration.

How to add additional environment configuration

Sometimes the Debug and Release environments can't meet our needs, so we need to add more environment configurations.
Open the menu generation -- > configuration manager and create a TEST1 environment

Then right-click web Config select Add configuration transformation (fourth)

Will automatically generate a web TEST1. Config file, which is very user-friendly. Then we configure some parameters in this file.

Change the configuration of the publication to publish.

Open the web after publishing successfully Config file

The effect is consistent with the expectation.

Multi environment configuration under aspnetcore

The configuration file in aspnetcore is called Appsettings Replaced by JSON NET Core is configured to use one or more Configuration provider Executed. The configuration provider uses various configuration sources to read configuration data from key value pairs:

What is a configuration provider

The following table shows NET Core application.

Provider Provides configuration through
Azure application configuration provider Azure application configuration
Azure Key Vault configuration provider Azure Key Vault
Command line configuration provider Command line parameters
Custom configuration provider Custom source
Environment variable configuration provider environment variable
Profile provider JSON, XML, and INI files
Key per file configuration provider Catalog file
Memory configuration provider In memory collection
Application secret (secret manager) Files in the user profile directory

Refer to for details Configuration in. NET
https://docs.microsoft.com/zh-cn/dotnet/core/extensions/configuration
The following parts are worth noting

Highlight: the configuration provider added later will replace the previous key settings
appsettings.Development.json is better than Appsettings JSON is loaded later, and the later loaded will overwrite the value of the first loaded configuration. There is no problem!

How to load a multi environment configuration file

In order to thoroughly understand the underlying loading logic, download the source code to find out.

builder.ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;

            config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

            if (env.IsDevelopment())
            {
                if (!string.IsNullOrEmpty(env.ApplicationName))
                {
                    var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                    if (appAssembly != null)
                    {
                        config.AddUserSecrets(appAssembly, optional: true);
                    }
                }
            }

            config.AddEnvironmentVariables();

            if (args != null)
            {
                config.AddCommandLine(args);
            }
        })

In the default WebHostBuilder implementation, use the environment variable env Load the json file spliced by the environmentname value. This is why Appsettings is loaded in the development phase Development. The principle of json configuration file.

Multi environment in development stage

How to transfer parameters to modify the value of the environment variable EnvironmentName is the key to the problem. If you can modify the desired value, then create a configuration file with the corresponding name.
There is a file in the web root directory: properties / launchsettings json
There is a configuration for configuring environment variables

"environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
},

During local development, you only need to create multiple startup configurations and set different aspnetcore respectively_ Environment can be switched. The modified launchsettings json

// launchSettings.json
{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:2364",
      "sslPort": 44302
    }
  },
  "profiles": {
    "Web1": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "https://localhost:7006;http://localhost:5006",
      "dotnetRunMessages": true
    },
    "Web1:Test": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "TEST"
      },
      "applicationUrl": "https://localhost:7006;http://localhost:5006",
      "dotnetRunMessages": true
    }
  }
}

Web1 and Web1:Test startup options will be displayed synchronously in VS Startup options. Switch to Web1:Test and run the program again to load Appsettings TEST. JSON, effects and Appsettings Development. JSON makes no difference.

Implementation of multi environment configuration in release phase

In the above, we learned to configure multiple different environment configurations locally for development. If there are many configurations of the production environment to be released, how can the program automatically load different configuration files? After all, launchsettings JSON files are only used with VS during development, since launchsettings JSON can configure environment variables. Without it, we can create environment variables manually. Add environment variables to the operating system, such as:


You can also set the environment value by passing parameters from the command line when the program starts.
But I don't think it's convenient for both. We hope that after the program is released according to different environments, it only needs to be executed directly, rather than additional configuration or parameter transfer.

EnvironmentName property

There is an EnvironmentName attribute in the project file of the project. You can specify the current EnvironmentName value and add the following code

Then, after compiling and running directly, you can read Appsettings TEST. JSON configuration file.
This configuration does not override launchsettings The environment value specified in JSON, but it affects the EnvironmentName value after publishing, so you can change the default EnvironmentName value after publishing.
After this setting, isn't it that the value of EnvironmentName after publishing can only be Test? If you want to publish other environments, don't you have to modify this value every time before publishing?
Yes, if there is no other means, it would be superfluous. Please see the figure below.

See, we only need to configure one more PublishProfile publishing file, specify different configuration items, and then control the EnvironmentName in combination with the Condition conditions.

So far, the perfect realization is to select different release files and release projects according to different environments. The target machine does not need to be configured. Direct operation is the effect we want.
Summary although ASP Net and ASP NETCORE implements multiple environments in different ways, but we can achieve the same effect when publishing finally. All configurations are one-time, and the corresponding PublishProfile can be specified when publishing.

Tags: C# .NET aspnetcore

Posted by otuatail on Sat, 16 Apr 2022 23:33:57 +0930