add-migration can not read the connection string from the file appsettings.json because of the path to appsettings.json

asp.net-core asp.net-core-2.0 asp-net-core-spa-services c# entity-framework-core

Question

Tools: VS2017, ASP.NET Core 2, Entity Framework Core 2, ASP.NET Core JavaScript Services

I am using the following BuildWebHost methode:

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
    .UseContentRoot(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName))
    .UseStartup<Startup>()
    .UseNLog()
    .Build();

For loading the connection string I have the following code in ConfigureServices (startup.cs):

Action<DbContextOptionsBuilder> optionsAction = options =>
    options.UseSqlServer(Configuration.GetConnectionString("RecipeDatabase")); 
services.AddDbContext<RecipeContext>(optionsAction);

With the above configuration the app runs without problems in debug mode and as windows service (after publishing).

But if I run add-migration the tool is not able to load the connection string from appsettings.json:

enter image description here

If I comment the following line like so

//.UseContentRoot(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName))

add-migration runs without problems but the app running as "Windows Service" not because it will not find the appsettings.json file.

How can I modify the configuration so that it is not necessary to comment the above line anymore?

Thank you.

Michael

1
3
3/25/2018 9:03:53 PM

Accepted Answer

You might want to override OnConfiguring method in your DbContext. Here is an example I'm using. It will work whenever you are using command line or windows service:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (optionsBuilder.IsConfigured)
    {
        base.OnConfiguring(optionsBuilder);
        return;
    }

    string pathToContentRoot = Directory.GetCurrentDirectory();
    string json = Path.Combine(pathToContentRoot, "appsettings.json");

    if (!File.Exists(json))
    {
        string pathToExe = Process.GetCurrentProcess().MainModule.FileName;
        pathToContentRoot = Path.GetDirectoryName(pathToExe);
    }

    IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
        .SetBasePath(pathToContentRoot)
        .AddJsonFile("appsettings.json");

    IConfiguration configuration = configurationBuilder.Build();

    optionsBuilder.UseSqlServer(configuration.GetConnectionString("RecipeDatabase"));

    base.OnConfiguring(optionsBuilder);
}
4
3/27/2018 11:09:18 AM

Popular Answer

In development environment, it's preferred to use "User Secrets" for storing configuration rather than appsettings.json. You get User Secrets on Solution Explorer > Project's Context Menu > Manage User Secrets.

User Secrets stores configuration in current user's romaing profile directory for example: C:\users\john\AppData\Roaming\Microsoft\UserSecrets\ProjectName012822aasd\secrets.json

While User Secrets option is meant only for development environment, for production you need to rely on other configuration management for example: Azure App Service's App Config.

Here's Microsoft's documentation on User Secrets



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow