简体   繁体   中英

ASP.NET Core Configuration Section in Startup

I am migrating a ASP.NET 5 RC1 project to ASP.NET Core, and have come across an interesting issue I've not yet seen, or found a solution for.

In order to use configuration settings within Startup I have previously retrived the configuration the following way

// Works fine for DI both in ASP.NET 5 RC1 and ASP.NET Core
services.Configure<SomeConfigurationClass>(Configuration.GetSection("SomeConfigurationSection"));

// How I previous retrieved the configuration for use in startup. 
// No longer available in ASP.NET Core
var someConfigurationToUseLater = Configuration.Get<SomeConfigurationClass>("SomeConfigurationSection");

After updating to ASP.NET Core 1.0 it seems Configuration.Get<T>() is no longer available.

I have tried updating the code to use Configuration.GetValue<T>() however this does not seem to work with objects and will only work when providing a path to a value. This has left me with a workaround for most of my configuration classes like so

var someConfigurationName = "someConfiguration";    
var someConfigurationClass = new SomeConfigurationClass()
{
    Value1 = Configuration.GetValue<string>($"{someConfigurationName}:value1"),
    Foo = Configuration.GetValue<string>($"{someConfigurationName}:foo"),
    Bar = Configuration.GetValue<string>($"{someConfigurationName}:bar")
};

However this is an issue when the configuration class contains an array of objects. In my case an array of Client objects

public class ClientConfiguration
{
    public Client[] Clients { get; set; }
}

With the following configuration

"configuredClients": {
  "clients": [
    {
      "clientName": "Client1",
      "clientId": "Client1"
    },
    {
      "clientName": "Client2",
      "clientId": "Client2"
    }
  ]
}

Where this would previously bind to the Clients property of my configuration class no problem, I can no longer find a way of doing so in ASP.NET Core 1.0

Updated Answer
For ASP Core 1.1.0 generic model binding is now done using Get :

var config = Configuration.GetSection("configuredClients").Get<ClientConfiguration>();

Original Answer
How about this:

var config = Configuration.GetSection("configuredClients").Bind<ClientConfiguration>();

With ASP.NET Core 2.0 (basically Core 1.1+), the IConfiguration is injected to Startup , and that can be used within ConfigureServices() and Configure() methods.

As shown in the accepted answer, the configuration can be bound to an object. But if just one value is required, the key based approach works well.

The IConfiguration still works with colon : separated string keys. And for array , use 0-based index. Or use the the generic getValue<T>() method with same keys. See example below:

var clientId2 = Configuration["configuredClients:clients:1:clientId"]?.ToString();
var clientName1 = Configuration.GetValue<string>("configuredClients:clients:0:clientName");

To use the same configuration values in other classes (eg Controllers)

  1. Either inject the IConfiguration and use the same key-based approach like above. Or
  2. Register an instance of the strongly-typed configuration object with the DI container, and inject that object directly into client classes.

Sample code below:

//In Startup.ConfigureServices()
var clientConfig = Configuration.GetSection("configuredClients")
    .Get<ClientConfiguration>();
services.AddSingleton(clientConfig);

//Controller
public class TestController : Controller
{
    IConfiguration _configStore;
    ClientConfiguration _clientConfiguration;

    public TestController(IConfiguration configuration, 
        ClientConfiguration clientConfiguration)
    {
        _configStore = configuration;
        _clientConfiguration = clientConfiguration;
    }

    public IActionResult Get()
    {
        //with IConfiguration
        var clientId1 = _configStore
            .GetValue<string>("configuredClients:clients:0:clientId");

        //with strongly typed ClientConfiguration
        var clientName1 = _clientConfiguration.Clients[0]?.ClientName;

        return new OkObjectResult("Configuration test");
    }
}

More examples here .

You don't read the configuration manually generally in ASP.NET Core yourself, instead you create an object that matches your definition. You can read more on that in the official documentation here .

Eg

public class MyOptions
{
    public string Option1 { get; set; }
    public int Option2 { get; set; }
}

public void ConfigureServices(IServiceCollection services)
{
    // Setup options with DI
    services.AddOptions();
    services.Configure<MyOptions>(Configuration);
}

Then you just inject the options IOptions<MyOptions> where you need them.

If you want to get first "clientName"(expected "Client1"), just write:

Configuration.GetSection("configuredClients")["clients:0:clientName"];

Update for comment

Install .NET Core 1.0.1 and go with @TomMakin's way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM