Getting value from appSettings.json?

I cannot get the value set in appsettings.json, when I run the code below I get the error System.NullReferenceException: 'Object reference not set to an instance of an object.'

What am I doing wrong?

public static IConfigurationRoot Configuration { get; } 
....
string facebookApiId = Configuration.GetValue<string>("Authentication:Facebook:AppId");

      

appSettings.json

"Authentication": {
  "Facebook": {
    "IsEnabled": "false",
    "AppId": "somevalue1",
    "AppSecret": "somevalue2"
  },
  "Google": {
    "IsEnabled": "false",
    "ClientId": "somevalue3",
    "ClientSecret": "somevalue4"
  }

      

Startup.cs

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
}

public IConfigurationRoot Configuration { get; }

      

+3


source to share


1 answer


In your code, you actually have 2 (two) Configuration

properties, one in Startup

, which is good as it gets populated and stored in an instance field, and one in an unnamed controller that is equal static

and never seems to be instantiated .

According to the MSDN article on configuration, the recommended way to expose your parameters to controllers is to implement the base option and logic of the config object, something like this:

// option mapping classes
public class FacebookOptions
{
    // maybe string here
    public bool IsEnabled { get; set; }
    public string AppId { get; set; }
    public string AppSecret { get; set; }
}

public class GoogleOptions
{
    // maybe string here
    public bool IsEnabled { get; set; }
    public string ClientId { get; set; }
    public string ClientSecret { get; set; }
}

// load configuration
public Startup(IHostingEnvironment env)
{
    // Set up configuration sources.
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appSettings.json", optional: true, reloadOnChange: true);

    Configuration = builder.Build();
}

// map the configuration to object
public void ConfigureServices(IServiceCollection services)
{
    // Adds services required for using options.
    services.AddOptions();

    // Register the IConfiguration instance which options binds against.
    services.Configure<FacebookOptions>(Configuration.GetSection("Facebook"));
    services.Configure<GoogleOptions>(Configuration.GetSection("Google"));

    // Add framework services.
    services.AddMvc();
}

      

Now you can easily get options on your controller via dependency injection:



public class GoogleController : Controller
{
    private readonly GoogleOptions _googleOptions;

    public GoogleController(IOptions<GoogleOptions> googleOptionsAccessor)
    {
        _googleOptions = googleOptionsAccessor.Value;
    }
}

      

If you want a complete configuration, you can add some kind of generic class containing all the parameters and use object graph mapping from the same article:

public class Authentication
{
    public FacebookOptions Google { get; set; }
    public GoogleOptions Google { get; set; }
}

// load configuration
public Startup(IHostingEnvironment env)
{
    // Set up configuration sources.
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appSettings.json", optional: true, reloadOnChange: true);

    Configuration = builder.Build();

    var options = new Authentication();
    config.GetSection("Authentication").Bind(options);
}

      

Edit: Make sure your classes and config sections are named the same as this is important as it turns out.

+6


source







All Articles