Skip to content

A Brief Introduction to Environment Name Configuration and Application in ASP.NET Core

TLDR

  • ASP.NET Core uses the ASPNETCORE_ENVIRONMENT environment variable to distinguish between execution environments (e.g., Development, Staging, Production).
  • The configuration loading mechanism follows a "last-in-wins" approach; the system automatically loads appsettings.json followed by appsettings.{EnvironmentName}.json.
  • Manually reloading configuration files in code may cause expected environment settings to be overwritten.
  • For local development, configure via launchSettings.json; for IIS deployment, add the <EnvironmentName> tag to the Publish Profile XML; for Docker, use the ENV instruction.
  • At runtime, you can inject IWebHostEnvironment and use IsDevelopment(), IsStaging(), IsProduction(), or IsEnvironment() to determine the current environment.

Configuration and Environment Name Mechanism

In .NET Core and later versions, the EnvironmentName environment variable is the core mechanism for distinguishing execution environments. ASP.NET Core provides three default environments:

  • Development: Used for local development.
  • Staging: Used for pre-release versions.
  • Production: The default environment if no environment variable is set.

Unlike the Transform mechanism used by Web.config in the legacy .NET Framework, ASP.NET Core employs an appsettings.json override logic. When the system executes WebApplication.CreateBuilder(args), it automatically calls ConfigureDefaults() and loads configuration files in the following order:

csharp
builder.ConfigureAppConfiguration((hostingContext, config) => {
    IHostEnvironment env = hostingContext.HostingEnvironment;
    // Settings loaded later will override those loaded earlier
    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: reloadOnChange)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: reloadOnChange);
    
    // ... other configurations
})

WARNING

Under what circumstances might configuration issues occur? If a developer manually reloads appsettings.json in Program.cs, it may overwrite the appsettings.{EnvironmentName}.json automatically loaded by the system. If you find that environment settings are not taking effect, please check if there is any unnecessary redundant loading logic in Program.

Methods for Setting Environment Variables

Local Development

Configure via Properties\launchSettings.json under the project. This setting overrides global environment variables and affects Visual Studio execution settings:

json
{
  "profiles": {
    "Sample": {
      "commandName": "Project",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Publishing to IIS using Visual Studio

To specify the deployment environment, add the <EnvironmentName> tag to the Publish Profile (.pubxml) XML:

xml
<PropertyGroup>
  <EnvironmentName>Staging</EnvironmentName>
</PropertyGroup>

After publishing, the web.config for IIS will automatically generate the corresponding environment variable settings:

xml
<aspNetCore ...>
  <environmentVariables>
    <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
  </environmentVariables>
</aspNetCore>

TIP

Under what circumstances might it be impossible to exclude extra files? In ASP.NET Core, the legacy Web.config <ExcludeFilesFromDeployment> setting is no longer effective, so it is not possible to exclude unnecessary appsettings.{Environment}.json files using this method.

Configuring with Dockerfile

In a Docker container, you can specify the environment directly in the Dockerfile using the ENV instruction:

dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
ENV ASPNETCORE_ENVIRONMENT=Staging

Working with Environment Settings

Developers can inject the IWebHostEnvironment interface to determine the current environment at runtime.

  • Determination method: Use extension methods such as IsDevelopment(), IsStaging(), or IsProduction().
  • Custom environments: If using a non-default environment name, you can use IsEnvironment("{environmentName}") to perform the check.

Change Log

  • 2024-07-12 Initial version created.