Reputation: 17879
In prior versions of ASP.NET Core we could dynamically add appsetting.json files with the environment suffix like appsettings.Production.json
for production environment.
Since the structure is a bit different, it seems that the configuration now got loaded in class Program
. But we dont have the `` injected here,so I tried it myself using environment variable:
public class Program {
public static void Main(string[] args) {
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) {
string envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
string envConfigFile = $"appsettings.{envName}.json";
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(envConfigFile, optional: true);
var finalConfig = config.Build();
return WebHost.CreateDefaultBuilder(args)
.UseUrls("http://0.0.0.0:5000")
.UseConfiguration(finalConfig)
.UseStartup<Startup>();
}
}
The code got executed but it doesn't override my appsettings.json
config. Let's say I have the following appsettings.json
:
{
"MyConnectionString": "Server=xxx,Database=xxx, ..."
}
This ConnectionString is working. Now I createappsettings.Development.json
{
"MyConnectionString": ""
}
and set ASPNETCORE_ENVIRONMENT=Development
. This should definitely throw an exception. But the app start correctly with the ConnectionString from appsettings.json
.
According to ASP.NET Core 2 configuration changes, the WebHost.CreateDefaultBuilder
method should itself use the new ConfigureAppConfiguration
approach and load environment specific config by default. Also the official docs say that appsettings.{Environment}.json
are loaded automatically. But this doesn't work and also loading it manually like this doesn't solve the problem:
return WebHost.CreateDefaultBuilder(args)
.UseUrls("http://0.0.0.0:5000")
.ConfigureAppConfiguration((builderContext, config) => {
IHostingEnvironment env = builderContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.UseStartup<Startup>();
How can I override the config using "appsettings.{envName}.json"
pattern? I liked that cause it was handy to override env specific things in ASP.NET Core.
Upvotes: 1
Views: 13181
Reputation: 35
Environment variable Settings Image
Based on Enviroment Variables settings we can use appsettings.environment.json file as config file
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();
}
Upvotes: 2
Reputation: 3908
According to docs, the JSON Configuration Provider should automatically load twice in ASP.NET Core 2.1 (and
ASP.NET Core 2.1)
when using CreateDefaultBuilder
(so move your code from the separate ConfigurationBuilder
).
AddJsonFile is automatically called twice when you initialize a new WebHostBuilder with CreateDefaultBuilder. The method is called to load configuration from:
- appsettings.json – This file is read first. The environment version of the file can override the values provided by the appsettings.json file.
- appsettings.{Environment}.json – The environment version of the file is loaded based on the IHostingEnvironment.EnvironmentName.
Their example:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory());
config.AddJsonFile(
"config.json", optional: true, reloadOnChange: true);
})
(If you want to use connection strings from your startup (UI MVC) project, for adding migrations in a different migrations project you may want to check this answer.)
Upvotes: 4
Reputation: 28
You should check your build settings. If you want your project to load an specific environment then you should specify to the compiler wish environment settings you want to be loaded.
I hope it helps. Good luck.
Upvotes: 0
Reputation: 17879
Found out that I had a custom DesignTimeDbContextFactory
class for migrations:
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext> {
public ApplicationDbContext CreateDbContext(string[] args) {
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
string connectionString = Config.GetConnectionString("AppDbContext");
builder.UseMySql(connectionString);
return new ApplicationDbContext(builder.Options);
}
}
Since the injection of the configratuion doesn't seem to work here (at the time I got errors for my connection strings when using default Startup
class), I wrote some custom configuration class:
public class Config {
static IConfigurationRoot config;
static IConfigurationRoot AppConfig {
get {
if (config == null) {
config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
}
return config;
}
}
public static string GetConnectionString(string name) {
var connectionString = AppConfig.GetConnectionString(name);
return connectionString;
}
}
So the problem was, that ASP.NET Core's default ConfigureAppConfiguration
wasn't used for consistence. Instead my solution only loads appsettings.json
since at the time of writing this class, no environment specific config was used.
I simply need to add loading here like this:
static IConfigurationRoot AppConfig {
get {
if (config == null) {
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
// https://github.com/aspnet/MetaPackages/blob/rel/2.0.0/src/Microsoft.AspNetCore/WebHost.cs
.AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true)
.Build();
}
return config;
}
}
I'd appreciate it if someone has a cleaner solution here that let me use the default ConfigureAppConfiguration
approach in EF migrations, cause it seems less error prone when using such default stuff instead of customized methods.
Upvotes: 5
Reputation: 2163
Try using CreateDefaultBuilder()
which should provide you with the configuration settings you want (as in the example in the docs). Note that if you are running on Linux it is case sensitive - if the file name has a capital P for Production, the value of the environment variable must as well. Also, check you have the files in the correct directory - print the value of Directory.CurrentDirectory()
at runtime. This is where they should be.
If this works but you don't actually want a default builder, just copy the parts you need from the source.
Upvotes: 0
Reputation: 5860
You need to go to your solution in visual studio 2017c click on the solution, in menu click properties > build and you’ll see That environment variable has already been created for the environment named Development. If you override that value within the properties page for your given web project , it will pull the environment variables from the app environment specific app settings . I would also just keep your web host builder default code if your version is 2.1 or above
Upvotes: 0