Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core 2.1 app not picking up appsettings.Development.json even though I specify ASPNETCORE_ENVIRONENT=Development explicitly. Why?

So I am working on an ASP.NET Core 2.1 Web API. I specified two sets of configurations for "Development" and "Production" explicitly by the following two functions:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<DataContext>(option => option
        .UseMySql(Configuration.GetConnectionString("DefaultConnection"))                                              
}

public void ConfigureDevelopmentServices(IServiceCollection services)
{
    services.AddDbContext<DataContext>(option => option
        .UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
}

In the appsettings.json, I have:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost; Database=datingApp; Uid=appuser; Pwd=zhanxucong"
    }
}

In the appsettings.Development.json, I have:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    },
    "ConnectionStrings": {
      "DefaultConnection": "Data Source=DatingApp.db"
    }
  }
}

When I learned through the tutorial, the instructor said that by convention, when ASPNETCORE_ENVIRONMENT=Development is set, ASP.NET Core will call the more specific configure function (i.e. ConfigureDevelopmentServices) and use the more specific appsettings config file (i.e. appsettings.Development.json). And I can confirm that it had worked fine on my Windows and Mac. However, when I run this app on Linux, after running ef migration with the above settings, I get the following errors:

info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 2.1.4-rtm-31024 initialized 'DataContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: None
System.ArgumentException: Keyword not supported: 'server'.
   at Microsoft.Data.Sqlite.SqliteConnectionStringBuilder.GetIndex(String keyword)
   at Microsoft.Data.Sqlite.SqliteConnectionStringBuilder.set_Item(String keyword, Object value)
   at System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(String value)
   at Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteRelationalConnection.CreateReadOnlyConnection()
   at Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteDatabaseCreator.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_1.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Keyword not supported: 'server'.

Any idea why this error will happen? Is it related to Linux being case-sensitive? Thanks!

Update: My Program class and my StartUp class (default ctor provided by dotnet-cli tool by running "dotnet new webapi":

Program class:

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

StartUp class:

public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    // ConfigureServices, ConfigureDevelopmentServices, Configure methods.
}
like image 344
Xucong Avatar asked Oct 04 '18 03:10

Xucong


People also ask

How do you check if current environment is development or not?

If you need to check whether the application is running in a particular environment, use env. IsEnvironment("environmentname") since it will correctly ignore case (instead of checking if env. EnvironmentName == "Development" for example).

What is difference between Appsettings json and Appsettings development json?

NET Core and as far as I see from my search on the web, appsettings.Development. json is used for development config while developing the app and appsettings. Production. json is used on the published app in production server.


1 Answers

Thanks for all the answers provided. I really appreciate it and I learned a lot.

As for my bug, it is actually due to a very stupid mistake:

In my appsettings.Development.json file, the "ConnectionStrings" is nested within "Logging". Therefore, when the ConfigureDevelopmentServices method is invoked, it will not be able to find ConnectionStrings in the appsettings.Development.json file and will fall back to configurations specified in appsettings.json, which is configured for connecting to a MySQL database. Hence the errors shown in my problem statement.

This observation is inspired by this GitHub issue.

like image 185
Xucong Avatar answered Oct 02 '22 09:10

Xucong