25

In previous versions of ASP.NET many of us used Web.Debug.config/Web.Release.config files trasformations that would look something like this:

Web.config:

<connectionStrings>
  <add name="AppDB" connectionString="Data Source=(LocalDb)\\..." />
</connectionStrings>

Web.Release.config:

<connectionStrings>
  <add name="AppDB" connectionString="Data Source=(ReleaseDb)\\..."  xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>

As per ASP.NET vNext tutorial you still can use Web.config. But config.json appear to be the new way to handle configurations now as per the same article:

config.json

{
    "Data": {
        "DefaultConnection": { 
            "ConnectionString": "Server=(localdb)\\..."
        }
    }
}

And in Startup.cs:

var configuration = new Configuration();
configuration.AddJsonFile("config.json");
configuration.AddEnvironmentVariables();

So I'm wondering what would be the suggested way to handle config-transofrmation with this shift to json?

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
2ooom
  • 1,760
  • 1
  • 23
  • 37

3 Answers3

20

vNext uses a new configuration system in which you can read the environment variables through code. So, in this case you would check for the presence of the appropriate environment variable and include the corresponding JSON through code.

For example, you can create a qa.json and prod.json. Set an environment variable, say, "ENV" that points to "qa" and "prod" in those respective environments. Then conditionally you can add the appropriate JSON.

The code could look like this:

1) default.json contains all your default stuff.

2) qa.json and prod.json contain the necessary overrides.

3) Since qa.json and prod.json come later, they will win. If there is a "setting1" in default.json and qa.json, it will automatically pick up the "setting1" in qa.json

 var configuration = new Configuration()
                     .AddJsonFile("default.json")
                     .AddEnvironmentVariables(); 

 var envSpecificJson = configuration.Get("ENV") + ".json";
 configuration.AddJsonFile(envSpecificJson);
A-Sharabiani
  • 17,750
  • 17
  • 113
  • 128
govin
  • 6,445
  • 5
  • 43
  • 56
  • The order of precedence is that "last in wins," so with this approach you're saying "default to the values in `default.json`, override that with anything found in environment variables, and override that with anything in {envSpecificJson}." The recommended approach is for environment variables to override any file-based configuration values. The default template now uses: .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables(); – Joel C Aug 31 '16 at 01:40
4

While the previous answer(s) offers a good solution I would like to present an alternate one:

Code

var configuration = new Configuration()
                     .AddJsonFile("config.json")
                     .AddEnvironmentVariables();

Local environment: Here you have the "config.json" file with all the settings. It is easily edited and maintained.

Prod environment: When deploying you omit the "config.json" file. As it is missing, the code will look for the next source in the chain which is the environment variables. Thus, when on your local machine, use the config file. When on the server, fall back to the environment variables. Note that the config keys must obviously be named the same in the file and the environment variables.

Emil Lundin
  • 577
  • 5
  • 14
  • 8
    you don't need to omit the `config.json` if there are environmentvariables it will override those on `config.json` and this is the recommended workflow for things like connection string. – Bart Calixto Apr 07 '15 at 19:50
2

By default, ASP.NET will check for an environment variable named "ASPNET_ENV" to set IHostingEnvironment's EnvironmentName variable.

The relevant code can be seen here:

https://github.com/aspnet/Hosting/blob/77e2dc263f11655312d4c73bb8e22d7b6254d485/src/Microsoft.AspNet.Hosting/HostingFactory.cs

You could do something like the following if you change ASPNET_ENV's value on the servers in your various environments:

var configuration = new Configuration()
            .AddJsonFile("config.json")
            .AddEnvironmentVariables();
if (string.Equals(env.EnvironmentName, "Prod", StringComparison.OrdinalIgnoreCase))
{
            configuration.AddJsonFile("prod.config.json");
}
Jarrel
  • 36
  • 2