7

I'm working on a .NET Core 2.1.103 WebAPI application that consists of multiple projects. Each project needs to have its own appsettings.json file. Each project is in its own subdirectory within a master "solution" folder. Here's a simplified version of the directory structure with the relevant directories for my question:

c:\code\my_big_solution
c:\code\my_big_solution\project1
c:\code\my_big_solution\project1\bin\Debug
c:\code\my_big_solution\project2
c:\code\my_big_solution\project2\bin\Debug
c:\code\my_big_solution\project3
c:\code\my_big_solution\project3\bin\Debug

I am having difficulty figuring out where each appsettings.json file must go and how to read them in. I assume from reading other posts that I should automatically copy each project's appsettings.json file to its associated bin\Debug directory. If that's the case, I'm not sure how to work with the Startup constructor. My understanding is that this is the .NET Core 2.0 way of reading a value from an appsettings.json file:

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
        string myString = Configuration["blah:blah:blah"];

configuration appears to be getting its appsettings.json file from c:\code\my_big_solution, not c:\code\my_big_solution\project1\bin\Debug or whatever project's Debug directory I want to pull from.

I can't figure out how to pull from the desired directory, other than doing a .NET Core 1.x sort of way of doing it, and that's by changing the constructor so it's passing in an IHostingEnvironment and using a ConstructorBuilder:

 public Startup(IHostingEnvironment env)
 {
     var builder = new ConfigurationBuilder()
         .SetBasePath(env.ContentRootPath ) // This line is wrong, but the correct path would be set here
         .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
         .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
         .AddEnvironmentVariables();

     Configuration = builder.Build();
     string myString = Configuration["blah:blah:blah"];

Although the second solution would work, this bugs me because I'm thinking there is a more "correct" way to do this in .NET Core 2.0. Is there?

Andr
  • 1,043
  • 4
  • 13
  • 15

2 Answers2

9

I figured out what was going on. In the launch.json file, I didn't have the correct path set for the cwd parameter. That's why Startup() was looking for the appsettings.json file in the wrong place.

Andr
  • 1,043
  • 4
  • 13
  • 15
6

As you're probably aware, the executing project determines where it looks for the appsettings.json file.

This means by default, in an ASP.NET Core 2 project, the WebHost.CreateDefaultBinder loads the appsettingsjson from the executing project content root of that project.

If your other projects are class libraries, then having a separate appsettings.json for each of those will have no effect. Only an executable program, like the WebAPI project you mention, will read it from its own root folder.

However, if all your projects are indeed executables, then it suffices to add the appsettings.json file in the root of each project and simply copy them to the output folder automatically by setting it through the .csproj:

  <ItemGroup>
    <Content Update="appsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </Content>
  </ItemGroup>

In your IDE, like Visual Studio or JetBrains Rider, you can also configure this visually by right-clicking on the properties.

N.B. If you want to use a single shared file between all projects, you might find this question to be of interest.

Juliën
  • 9,047
  • 7
  • 49
  • 80
  • 1
    The WebAPI project (and there are multiple WebAPI projects in this "solution") actually compiles down to a dll. So perhaps appsettings isn't the right mechanism to use here. I guess my question should be, where should you store preferences for a WebAPI dll if not in an appsettings.json file? – Andr Apr 18 '18 at 12:27