Automatically set appsettings.json for dev and release environments in asp.net core?
Asked Answered
G

14

238

I've defined some values in my appsettings.json for things like database connection strings, webapi locations and the like which are different for development, staging and live environments.

Is there a way to have multiple appsettings.json files (like appsettings.live.json, etc, etc) and have the asp.net app just 'know' which one to use based on the build configuration it's running?

Gaekwar answered 22/9, 2017 at 11:59 Comment(0)
M
33

You may use conditional compilation:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#if SOME_BUILD_FLAG_A
    .AddJsonFile($"appsettings.flag_a.json", optional: true)
#else
    .AddJsonFile($"appsettings.no_flag_a.json", optional: true)
#endif
    .AddEnvironmentVariables();
    this.configuration = builder.Build();
}
Muscolo answered 22/9, 2017 at 12:29 Comment(8)
You should set your environment variable in your MSBuild/TFS build. Conditional compilation leads to mistakes for something easily handled in CI builds. I.e., .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)Chronograph
See my answer (https://mcmap.net/q/116779/-automatically-set-appsettings-json-for-dev-and-release-environments-in-asp-net-core) for Environment variableHemorrhage
This kind of approach forces the code to be recompiled specifically for each environment, making it impossible to be redistributed/installed elsewhere.Meatball
Question was about “knowing about build configuration”Muscolo
This should not be marked as the accepted answer - though it is a solution it's not best practice.Barracuda
@Barracuda that's answer to question. But I'm agree that readers should know that such question means that they possibly misunderstand some aspnetcore basics. Please feel free to suggest edit to add some warning and best practice link(s).Muscolo
Not correct answer.The question is: how to set automatically for configuration. This answer has hard-code...Eugeniaeugenics
@AlexSham This is probably the best answer you could give, given that Microsoft seem to have shifted a lot of the build stuff to code, rather than xml files. Alas, you can't just automatically toggle Configuration/Environmental variables as they are usually Environmental variables of the OS.Timtima
D
235

Update for .NET Core 3.0+

  1. You can use CreateDefaultBuilder which will automatically build and pass a configuration object to your startup class:

    WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
    
    public class Startup
    {
        public Startup(IConfiguration configuration) // automatically injected
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }
        /* ... */
    }
    
  2. CreateDefaultBuilder automatically includes the appropriate appsettings.Environment.json file so add a separate appsettings file for each environment:

    appsettings.env.json

  3. Then set the ASPNETCORE_ENVIRONMENT environment variable when running / debugging

How to set Environment Variables

Depending on your IDE, there are a couple places dotnet projects traditionally look for environment variables:

  • For Visual Studio go to Project > Properties > Debug > Environment Variables:

    Visual Studio - Environment Variables

  • For Visual Studio Code, edit .vscode/launch.json > env:

    Visual Studio Code > Launch Environment

  • Using Launch Settings, edit Properties/launchSettings.json > environmentVariables:

    Launch Settings

    Which can also be selected from the Toolbar in Visual Studio

    Launch Settings Dropdown

  • Using dotnet CLI, use the appropriate syntax for setting environment variables per your OS

    Note: When an app is launched with dotnet run, launchSettings.json is read if available, and environmentVariables settings in launchSettings.json override environment variables.

How does Host.CreateDefaultBuilder work?

.NET Core 3.0 added Host.CreateDefaultBuilder under platform extensions which will provide a default initialization of IConfiguration which provides default configuration for the app in the following order:

  1. appsettings.json using the JSON configuration provider.
  2. appsettings.Environment.json using the JSON configuration provider. For example:
    • appsettings.Production.json or
    • appsettings.Development.json
  3. App secrets when the app runs in the Development environment.
  4. Environment variables using the Environment Variables configuration provider.
  5. Command-line arguments using the Command-line configuration provider.

Further Reading - MS Docs

Dunaville answered 31/3, 2020 at 22:54 Comment(7)
Thanks, it is good but How to do that with the console process (or worker process template/scaffolding)?Mehalick
This does not work with latest version, it will always take appsettings.json and ignore appsettings.development.json. Run (dev) and run (prod) is also missing.Erythrocytometer
This should be the accepted answer.Sedation
Would this work for custom environment names as well? For example, if I wanted to set ASPNETCORE_ENVIRONMENT as "Dev". Will an appsettings called appsettings.Dev.json be automatically picked up?Bibi
@Mehnaz, I believe so. I don't think you're bound by any preset available environment names. It'll just take whatever name you set in your environment variable and use that to build the naming rules for the app settings file.Dunaville
Does "Host" mean web hosting? I mean, I had been thinking so, but today, I created a .NET 7.0 console project, and to use DI, I had to add Hosting, and then to adjust logging, I had to add appsettings.[Development].json. But why does it need "ASPNETCORE_ENVIRONMENT"? Is it just a relic of the past, or is Hosting/appsettings for ASP.NET Core?Massey
I would add that if using VS2022, it is accessed via Debug > (ProjectName) Debug Properties.Brendanbrenden
A
156

I have added screenshots of a working environment, because it cost me several hours of R&D.

  1. First, add a key to your launch.json file.

    See the below screenshot, I have added Development as my environment.

    Declaration of the environment variable in launch.json

  2. Then, in your project, create a new appsettings.{environment}.json file that includes the name of the environment.

    In the following screenshot, look for two different files with the names:

    • appsettings.Development.Json
    • appSetting.json


    Project view of appsettings JSON files

  3. And finally, configure it to your StartUp class like this:

    public Startup(IHostingEnvironment env)
    {
        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();
    }
    
  4. And at last, you can run it from the command line like this:

    dotnet run --environment "Development"
    

    where "Development" is the name of my environment.

Airspace answered 22/9, 2017 at 12:19 Comment(3)
Tried this and it works great. VS2017 even displays the different versions as under the base file. up vote.Sauncho
how do you do it in core 2.2 as ihostingenvironment is deprectedPlumbery
@Plumbery you should use IWebHostEnvironment instead.Discriminatory
H
64

In ASP.NET Core you should rather use Environment Variables instead of build configuration for proper appsettings.json

  1. Right click on you project > Properties > Debug > Environment Variables

    environment variables

  2. ASP.NET Core will use the appropriate appsettings.json file:

    example of appsettings files in solution explorer

  3. Now you can use that Environment Variable like this:

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
    
        Configuration = builder.Build();
    }
    

Note: If you use @Dmitry's answer, you can run into problems eg. when overriding appsettings.json values on Azure.

Hemorrhage answered 14/5, 2018 at 13:44 Comment(0)
M
43

You can make use of environment variables and the ConfigurationBuilder class in your Startup constructor like this:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
    .AddEnvironmentVariables();
    this.configuration = builder.Build();
}

Then you create an appsettings.xxx.json file for every environment you need, with "xxx" being the environment name. Note that you can put all global configuration values in your "normal" appsettings.json file and only put the environment specific stuff into these new files.

Now you only need an environment variable called ASPNETCORE_ENVIRONMENT with some specific environment value ("live", "staging", "production", whatever). You can specify this variable in your project settings for your development environment, and of course you need to set it in your staging and production environments also. The way you do it there depends on what kind of environment this is.

UPDATE: I just realized you want to choose the appsettings.xxx.json based on your current build configuration. This cannot be achieved with my proposed solution and I don't know if there is a way to do this. The "environment variable" way, however, works and might as well be a good alternative to your approach.

Manutius answered 22/9, 2017 at 12:7 Comment(6)
I looked at using environment variables, in the project properties->debug section, however there's no obvious way how this will change based on project settings. Is that another file I can add to my project to handle it?Gaekwar
Setting the variable within the project properties will only work for using it in your development environment (probably Visual Studio). You will need to set it elsewhere for your deployed apps depending on the specific environment (IIS, Azure). I would not recommend to set the variable in some configuration file because this file might get deployed, too, and then override the server values.Manutius
You set it up in build configurations. If there is not a build configuration file then they are doing it manually, so they would need to set it up in the (archaic) deployment profileChronograph
I have multiple environments like test, staging and production in Azure. Where do I change ASPNETCORE_ENVIRONMENT variable if I want to publish the release build of web app from VS to Azure?Unselfish
We don't change the variables during deployment, instead, they are built in to the specific environment. In Azure, you can set these values directly within your app service configuration unter "Application settings". Don't forget to mark them as "Deployment slot settings" in case you're working with multiple slots.Manutius
In latest version environment variables are ignored!Erythrocytometer
M
33

You may use conditional compilation:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#if SOME_BUILD_FLAG_A
    .AddJsonFile($"appsettings.flag_a.json", optional: true)
#else
    .AddJsonFile($"appsettings.no_flag_a.json", optional: true)
#endif
    .AddEnvironmentVariables();
    this.configuration = builder.Build();
}
Muscolo answered 22/9, 2017 at 12:29 Comment(8)
You should set your environment variable in your MSBuild/TFS build. Conditional compilation leads to mistakes for something easily handled in CI builds. I.e., .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)Chronograph
See my answer (https://mcmap.net/q/116779/-automatically-set-appsettings-json-for-dev-and-release-environments-in-asp-net-core) for Environment variableHemorrhage
This kind of approach forces the code to be recompiled specifically for each environment, making it impossible to be redistributed/installed elsewhere.Meatball
Question was about “knowing about build configuration”Muscolo
This should not be marked as the accepted answer - though it is a solution it's not best practice.Barracuda
@Barracuda that's answer to question. But I'm agree that readers should know that such question means that they possibly misunderstand some aspnetcore basics. Please feel free to suggest edit to add some warning and best practice link(s).Muscolo
Not correct answer.The question is: how to set automatically for configuration. This answer has hard-code...Eugeniaeugenics
@AlexSham This is probably the best answer you could give, given that Microsoft seem to have shifted a lot of the build stuff to code, rather than xml files. Alas, you can't just automatically toggle Configuration/Environmental variables as they are usually Environmental variables of the OS.Timtima
A
33

Just an update for .NET core 2.0 users, you can specify application configuration after the call to CreateDefaultBuilder:

public class Program
{
   public static void Main(string[] args)
   {
      BuildWebHost(args).Run();
   }

   public static IWebHost BuildWebHost(string[] args) =>
      WebHost.CreateDefaultBuilder(args)
             .ConfigureAppConfiguration(ConfigConfiguration)
             .UseStartup<Startup>()
             .Build();

   static void ConfigConfiguration(WebHostBuilderContext ctx, IConfigurationBuilder config)
   {
            config.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("config.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"config.{ctx.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);

   }
 }
Assemblage answered 27/2, 2018 at 16:27 Comment(5)
How do you switch between the environments being used? Are there changes supposed to be made in any config file? I understand I'll need to add the URL I want to be using when the project runs on Azure to appsettings.json and the URL I want to execute when run locally (by F5) to appsettings.Development.json. Is that correct? My string that I want to be using is in the file launchSettings.json and I'm a bit unclear on how to alter it based on where the application is executed (or if it's supposed to be altered at all).Frieze
@Frieze The environment is nothing more than a setting specified in project properties. In VS 2017, right click on the project > properties. Under debug, you will see the current environment for key ASPNETCORE_ENVIRONMENT. The value is what will be replaced for ctx.HostingEnvironment.EnvironmentName}. So if you set that value in properties to 'Production', the project will look for config.Production.json file in the root folder. For more info, please view this linkAssemblage
Creates an Error CS0266 Cannot implicitly convert type 'Microsoft.AspNetCore.Hosting.IWebHost' to 'Microsoft.AspNetCore.Hosting.IWebHostBuilder'. An explicit conversion exists (are you missing a cast?) in WebHost.CreateDefaultBuiler(...Jussive
It's worth noting that here it states "AddJsonFile is automatically called twice when you initialize a new host builder with CreateDefaultBuilder". In other words, it is already loading appSettings.json and then based on your environment configuration, it is loading appsettings.{Environment}.jsonCoben
@umutsen In latest visual studio there is no more run environment settingsErythrocytometer
P
24
  1. Create multiple appSettings.$(Configuration).json files like:

    • appSettings.staging.json
    • appSettings.production.json
  2. Create a pre-build event on the project which copies the respective file to appSettings.json:

    copy appSettings.$(Configuration).json appSettings.json
    
  3. Use only appSettings.json in your Config Builder:

    var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();
    
    Configuration = builder.Build();
    
Pipette answered 15/1, 2019 at 17:45 Comment(6)
This should be an accepted answer. For complicated cases SlowCheetah may be used.Sura
How do you create a pre-build event on the project? Where should that line starting copy... actually be put?Cantonment
@Cantonment In Visual Studio, right-click on the Project in the Solution Explorer view, select Properties from the right-click menu, then select Build Events in the properties view.Kimmi
This is perfect - allows me to build the app and deploy our QA/Test and UAT onto the one machine without having to copy the app settings and using the above methods of setting it at machine level. Exactly what was needed - and I think what the person was looking for above.Jhelum
Where do you get the AddEnvironmentVariables extension from?Debussy
This does not work with .NET 6/7 (perhaps not even with earlier version). What this does is allowing you to read current environment variables through Configuration instance (e.g. var environmetnName = Configuration.GetValue<string>("DOTNET_ENVIRONMENT"))Barratry
S
24

This is version that works for me when using a console app without a web page:

var builder = new ConfigurationBuilder()
             .SetBasePath(Directory.GetCurrentDirectory())
             .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
             .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true);

            IConfigurationRoot configuration = builder.Build();
            AppSettings appSettings = new AppSettings();
            configuration.GetSection("AppSettings").Bind(appSettings);
Shaylyn answered 6/8, 2020 at 8:46 Comment(1)
You may need to add Microsoft.Extensions.Configuration.FileExtensions to your .net 6 project.Shaylyn
S
9

You can add the configuration name as the ASPNETCORE_ENVIRONMENT in the launchSettings.json as below

  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:58446/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "environmentVariables": {
        ASPNETCORE_ENVIRONMENT": "$(Configuration)"
      }
    }
  }
Sloppy answered 21/8, 2018 at 10:55 Comment(0)
H
7

By adding the environment name in between the "appsettings" and ".json" part of the filename, it will override any settings that are in the main appsettings.json file.

For example, in the likehood that you have a different SQL Server connection string for a production environment, you can add that connection string to appsettings.Production.json, and it will use the value from that file.

enter image description here

To choose the profile or environment, open launchSettings.json and set the environment in ASPNETCORE_ENVIRONMENT:

   "IIS Express": {
     "commandName": "IISExpress",
     "launchBrowser": true,
     "environmentVariables": {
       "ASPNETCORE_ENVIRONMENT": "Development"
     }
   }

and setup:

var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var builder = new ConfigurationBuilder()
    .AddJsonFile($"appsettings.json", true, true)
    .AddJsonFile($"appsettings.{environment}.json", true, true)
    .AddEnvironmentVariables();
Hohenzollern answered 30/10, 2022 at 4:37 Comment(0)
F
5

.vscode/launch.json file is only used by Visual Studio as well as /Properties/launchSettings.json file. Don't use these files in production.

The launchSettings.json file:

  1. Is only used on the local development machine.
  2. Is not deployed.
  3. contains profile settings.

    • Environment values set in launchSettings.json override values set in the system environment

To use a file 'appSettings.QA.json' for example. You can use 'ASPNETCORE_ENVIRONMENT'. Follow the steps below.

  1. Add a new Environment Variable on the host machine and call it 'ASPNETCORE_ENVIRONMENT'. Set its value to 'QA'.
  2. Create a file 'appSettings.QA.json' in your project. Add your configuration here.
  3. Deploy to the machine in step 1. Confirm 'appSettings.QA.json' is deployed.
  4. Load your website. Expect appSettings.QA.json to be used in here.
Femmine answered 31/5, 2020 at 12:38 Comment(1)
Does it meant, that if you have 5 environments and 5 appsettings.EnvName.json files, all of them will be deployed and just one selected machine because artifacts of the build definition will contain all 5 files ? Or only appsettings.json (as main) + appsettings.CurrentEnvironment.json (as overrides) should be deployed and how?Bigeye
I
2

For .NET 6.0+

Example launchSettings.json is as following

...
"profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": false,
      "launchUrl": "swagger",
      "applicationUrl": "http://localhost:5081",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
...

We can obtain ASPNETCORE_ENVIRONMENT section as following

Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

How I use as following, in which I am using PostgreSql.

public RepositoryContext CreateDbContext(string[] args)
{
    var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

    var configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile($"appsettings.{environmentName}.json")
        .Build();

    var builder = new DbContextOptionsBuilder<RepositoryContext>()
        .UseNpgsql(configuration.GetConnectionString("sqlConnection"));

    return new RepositoryContext(builder.Options);
}
Isham answered 16/6, 2023 at 17:48 Comment(0)
S
0

I had the same issue that I wanted to change the appsettings.*.json file based on my chosen configuration in VS and I just discovered that you can just put "$(Configuration)" as value for "ASPNETCORE_ENVIRONMENT" in your launchSettings.json.

This lets the default HostBuilder automatically pick the right appsettings.*.json-file.

I assume you still should do some other things so that your dev.appsettings won't be copied to production-server like described here for example Environment Based appsettings.json Configuration for publishing in .NET 5. But it does the trick to test different environment during development and inside VS w/o deploying to another server or to manually set the ASPNETCORE_ENVIRONMENT-variable.

BTW: I tested with VS. I am not sure whether this also works with VS-Code.

Spiel answered 12/7, 2022 at 7:20 Comment(0)
A
0

Keep appsettings.json similar to appsettings.Development.json It works automatically

Example appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Server=myserver;Database=mydb;User=myuser;Password=mypassword;"
  }
}

appsettings.Development.json

{
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*",
      "ConnectionStrings": {
        "DefaultConnection": "Server=myserver;Database=mydb;User=myuser;Password=mypassword;"
      }
    }
Aviary answered 24/7, 2023 at 8:46 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.