ASP.Net Core Configuration Environments
- See Docs
In .net framework we have configurations - "debug" and "release"- and you could add more (via Visual Studio Build/configuration manager. Asp.net automatically transformed the web.config xml so you could have different sets of appsettings/connection strings etc.
Environments is the core version of this. The term configuration still exists, in visual studio and "dotnet build -c release" / "dotnet publish -c Prod"
One major difference is the appsettings.json are NOT transformed like the web.config (but see SlowCheetah below). Therefore the typical deployment will have the original (debug) appsettings.json AND all the appsettings.env.json. The environment setting is used to select which env.config to load.
A buildserver can rewrite the appsettings.json (devops file transforms) but changing the build pipeline isn't quite as easy as changing a transform.
Environments
Environments are set in one (or more!) of:
- Environment variables DOTNET_ENVIRONMENT and/or (for ASP) ASPNETCORE_ENVIRONMENT
- Program arguments
- In code
Environment Variables
You can set environment variables in the web.config
<handlers>
<add name="aspNetCore" path="*" verb="*"
modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\Net6Web.dll"
stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout"
hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="TST" />
</environmentVariables>
</aspNetCore>
</system.webServer>
You can also set them in launchSettings.json:
"ASPNETCORE_ENVIRONMENT": "Development"
}
Set in code
- In Net6/WebApplication simply set EnvironmentName
var builder = WebApplication.CreateBuilder(args);
builder.Environment.EnvironmentName = "TST"; - In older .net (and .net 6 consoles), the Host.CreateDefaultBuilder.ConfigureAppConfiguration is the place to set it
var hostBuilder = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, builder) =>
{
context.HostingEnvironment.EnvironmentName = "TST";
})
Using the environment
It's just a free text string property: IWebHostEnvironment/IHostingEnvironment.EnvironmentName
- Static class Microsoft.Extensions.Hosting.Environments has fields for Development(default for debug), Staging and Production (default for publish).
- There are several extension methods to help check the environment
_logger.LogInformation($"Environment is {_webHostEnvironment.EnvironmentName}");
if (_webHostEnvironment.IsDevelopment()) { }
else if (_webHostEnvironment.IsProduction()) { }
else if (_webHostEnvironment.IsEnvironment("TST")) //case insensitive based on a name - Many companies use Debug, TST (internal testing), ACC (user acceptance) and [Prod]uction plus maybe others.
- Although you can define environments in the Visual Studio Configuration Manager (in the .sln file), you can add additional config environment names directly in the csproj
- There are several extension methods to help check the environment
If you define extra configurations in the csproj, remember to make them optimized builds.
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Configurations>Debug;Release;TST;ACC;PRD;</Configurations>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='TST|AnyCPU'">
<Optimize>True</Optimize>
</PropertyGroup>
During initialization
In Program.cs, the WebApplication exposes IWebHostEnvironment via .Environment
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
In the application (using DI)
- Controllers: IHostingEnvironment.EnvironmentName is the name; you can ask for IWebHostEnvironment in a controller constructor
- In Razor, there is an <Environment Include="TST" Exclude="ACC"
public RocketController(
ILogger<RocketController> logger,
IWebHostEnvironment webHostEnvironment)
{
_logger = logger;
_webHostEnvironment = webHostEnvironment;
}
[HttpGet("/LaunchRocket")]
public IActionResult LaunchRocket()
{
if (_webHostEnvironment.IsEnvironment("TST"))
{
return Content("In TST we don't launch rockets");
}
launchSettings.json
Properties\launchSettings.json is optional, and never deployed. From project properties, the Debug menu item has a link ("Open debug launch profiles UI") - it is also available on the toolbar Run menu (with a wrench symbol).
You can set the environment either as environmentVariables or as commandLineArgs (both shown here, for overkill!).
"profiles": {
"MyConsoleApp": {
"commandName": "Project",
"commandLineArgs": "Environment=development",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}
Config Transforms
In framework, .config xml can be transformed using xdt. In core, you can use Microsoft's Microsoft.VisualStudio.SlowCheetah (build-time nuget) which includes a json transformer. In the .csproj, appsettings.json has a subnode <TransformOnBuild>true while the DependentUpon appsettings.env.json has a <IsTransformFile>true subnode .
In Visual Studio right-click the appsettings.json and use SlowCheetah "Add Transforms". The transforms for all the configurations are created. They are NOT set to "Copy to output directory". But when you use publish (via Visual Studio or "dotnet publish -c Acc") it will apply the transform- the appsettings.json is the only file and it is transformed.