Reputation: 4517
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
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
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
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