CompanyDroneFromSector7G
CompanyDroneFromSector7G

Reputation: 4517

Configuration is empty

I'm trying to read config data from appsettings.json, which looks like this:

{
    Owner: {
        Name: "Dave",
        City: "Dusseldorf"
    }
}

In Startup.cs I have:

public Startup(IConfiguration configuration)
{
    var builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json");
    Configuration = builder.Build();
}

In my class I have

private readonly IConfiguration _configuration;

public MyClass(
    IConfiguration configuration
    )
{
    _configuration = configuration;
}

...and later in the same class

string name= _configuration["Owner.Name"];

But this is always empty. However, if I add a breakpoint on that line and expand the _configuration class I can see a list of Providers (Count = 5) including one for appsettings.json, and if I expand this I can see my setting values, including Name.

However these don't seem to be accessible from code.

Am I using the wrong class/namespace? How should I read these values?

Upvotes: 3

Views: 3812

Answers (3)

GeorgiG
GeorgiG

Reputation: 1093

One of the worst reasons this can happen is that your appsettings.json is not built (copied into the bin folder). Try right-clicking the file -> select properties and set to Copy if newer or Copy Always. That would make sure the file is properly copied and found by the configuration logic.

Upvotes: 3

Nkosi
Nkosi

Reputation: 246998

This may be more of a design issue. Shouldn't really be injecting IConfiguration out side of Startup.

Consider creating a POCO model of the desired configuration.

public class MyClassOptions {
    public string Name { get; set; }
    public string City { get; set; }
}

And have the target class depend on that strongly typed model

public class MyClass {

    private readonly MyClassOptions options;

    public MyClass(MyClassOptions options) {
        this.options = options;
    }

    public void SomeMethod() {
        string name = options.Name;
        string city = options.City;

        //...
    }

    //...
}

In Startup access the configuration as shown before but extract the desired configuration details.

public class Startup {
    IConfiguration Configuration;

    public Startup() {
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json");
        Configuration = builder.Build();
    }

    public void ConfigureServices(IServiceCollection services) {
        //Bind to object graph from configuration
        MyClassOptions options = Configuration.GetSection("Owner").Get<MyClassOptions>();
        //make it available to the service collection for Dependency Injection
        services.AddSingleton<MyClassOptions>(options);


        services.AddTransient<MyClass>();

        //...
    }
}

When MyClass is resolved, the options extracted from configuration will be injected.

This way the target class is not tightly coupled to framework details.

Upvotes: 1

tmaj
tmaj

Reputation: 34947

The configuration built via builder build needs to be added to available services.

var configuration = builder.Build(); 
services.AddSingleton<IConfiguration>(configuration);

Please note that your not showing us your real code (I.e Startup would not complie, it's missing return type declaration, we don't know what Configuration is) so I'm making guesses about your setup.

Upvotes: 1

Related Questions