ASP.NET Core Configuration Section in Startup

↘锁芯ラ 提交于 2019-12-18 13:52:24

问题


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


回答1:


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>();



回答2:


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 (e.g. 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.




回答3:


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.

E.g.

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.




回答4:


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.



来源:https://stackoverflow.com/questions/40397648/asp-net-core-configuration-section-in-startup

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!