ASP.NET Core documentation suggests we should use appsettings.json file, along with a file per environment, containing overriding values. The problem is that all these files are published, though only appsettings.json and appsettings.[Environment].json are relevant. The other problem is that to change a config value on server one must inspect both files: base and environment specific.
So my question is: what is the cleanest way to have one configuration file in each deployment environment?
The key difference is that ASP.NET Core apps are not deployed for a particular configuration, as ASP.NET apps were. Previously, you'd literally publish as "Release", for example, and if you wanted to switch the deployment config, you'd have to republish. With an ASP.NET Core app, the environment is determined by the ASPNETCORE_ENVIRONMENT
environment variable or by the environment passed during execution. As a result, it's perfectly valid to deploy all possible environmental settings, since the environment can be changed on a whim.
That said, if you know for sure you're never going to change the environment, you can simply remove any appsettings.{environment}.json
files you don't need. Additionally, you should not really override settings in the man appsettings.json
. If it's environment-specific, it should go in one of the environment-specific JSON files. Your main appsettings.json
file should really only contain global settings unaffected by environment. If you handle it in this way, then you don't have to look at both to see where the settings are coming from.
Finally, if you don't like this approach, in general, you can simply choose a different configuration strategy, such as environment variables or an external config source such as Azure Key Vault.
We can start by looking at the predefined ConfigurationBuilder
that usually looks something like this:
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
You can opt to remove the AddJosnFile()
if you don't want them in the first place, as sometimes your project may not require this.
If you do intend to use the appsettings.json
or similar, then it is important to note the order they are added. You can see in the code snippet above, that the appsettings.{env}.json
is added after.
This is an important concept to understand, because this means that if there is a file found that matches the filename (for example, appsettings.Production.json
), it will replace.override any overlapping configurations.
Note the use of the words replace, override and overlapping.
You can architect your own tiers and layer your configurations in a suitable way to fit your project. You are not restrained to have on use the env.EnviornmentName
either, you can use any kind of conditional logic to design it as needed.
If you plan to go this route of customized design. You may want to note that you can reconfigure and alter the configuration as much as you like prior to the WebHostBuilder
being built (i.e. before the .Build()
method is called). So, you can be very creative in how you want to programmatically configure your project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With