4

In an aspnetcore 2.0 project I'm trying to setup a single, shared appsettings.json file throughout my web application and several of my xunit test projects.

First off, everything works fine when I add the appsettings.json "regularly" to my projects individually. However, when I attempt to add a single reference/linked file from a different path, the values aren't read out during runtime.

To set this up, for each project I add the linked file to the .csproj:

<ItemGroup>
    <Content Include="..\Shared\appsettings.json">
        <Link>appsettings.json</Link>
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
</ItemGroup>

And on each build, I can verify it is output nicely to the /bin/Debug/netcoreapp2.0 directory:

Screenshot of output directory

The problem is that when reading it out, either through the default Startup of my webapi or in the tests, the settings values are always null. I'm using a strong typed configuration. In the webapi project, I'm using the WebHost.CreateDefaultBuilder() with the aspnetcore 2.0 conventions (which under the hood looks at hostingEnvironment.EnvironmentName, dotPeek tells me).

But also in the case of the test projects, the same occurs. Which all can be explained by the following example in my global test fixture:

var builder = new ConfigurationBuilder()
    // .SetBasePath(???)
    .AddJsonFile("appsettings.json");

var configuration = builder.Build();

var settings = new FooSettings();
configuration.GetSection("FooSettings").Bind(settings);

if (settings == null) throw new Exception("Could not find or parse 'appsettings.json'");

// The problem: always fails on this check
if (string.IsNullOrEmpty(settings.Bar)) throw new Exception("Could not find or parse 'FooSettings'");

The problem is commented on the last line in the above sample. Again, it works perfect when I directly add the appsettings.json file to the project root, instead of adding it as a linked reference to a shared folder. I am assuming I have to either change the .csproj configuration differently OR use a different .SetBasePath(???). But for both I'm struggling on how to achieve it.

The question: What can I do to make the linked appsettings file to be read properly in all my projects?

N.B. I found several other posts, but couldn't find any with a matching answer, specifically for dotnetcore.

Juliën
  • 9,047
  • 7
  • 49
  • 80
  • 1
    Have you looked through [this](https://andrewlock.net/sharing-appsettings-json-configuration-files-between-projects-in-asp-net-core/)? – levininja Apr 17 '18 at 22:22
  • 1
    Thanks @levininja. I think that is actually something that'll make it _work_. But... I agree with what the blog author mentions: "It's not a particularly elegant solution" and "this solution is a bit hacky". He also hints at the last line that there's probably a better solution that can be conjured up. – Juliën Apr 18 '18 at 20:39
  • I wonder if adding the reference to your project.json like [answer 1 on this post](https://stackoverflow.com/questions/37333368/how-do-you-add-a-file-as-a-link-in-a-net-core-library) would make it work. – levininja Apr 18 '18 at 20:54
  • @Juliën I face with the same issue, have you found any solution ? thanks ! – Christophe Gigax Feb 04 '19 at 15:10
  • 1
    It searches for appsettings.json in project dir not in output in some different environments. Add SetBasePath(Directory.GetCurrentDirectory()); – mr_squall Oct 26 '19 at 14:43

1 Answers1

0

It started working after i added some code in Program (thanks @mr_squall for direction..):

     public static void Main(string[] args)
        {
            CreateHostBuilder(args)
#if !DEBUG
                .UseContentRoot(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
#endif
                .Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
Community
  • 1
  • 1
Nick Kovalsky
  • 5,378
  • 2
  • 23
  • 50