简体   繁体   中英

Can't map instance from IConfiguration provider of appsettings.json

In my appsettings.test.json I have the following structure.

{
  "ViewOptionsConfiguration": {
    "Default": {
      "GroupingOptions": [
        { "Key": "SortKey1", "Label": "SortVal1" },
        { "Key": "SortKey2", "Label": "SortVal2" }
      ]
    }
  }
}

Then, I can read it using the following syntax (obtaining correct values).

string path = "ViewOptionsConfiguration:Default:GroupingOptions";

string key0 = config.GetValue<string>(path + ":0:Key")
string lab0 = config.GetValue<string>(path + ":0:Label")
string key1 = config.GetValue<string>(path + ":1:Label")
string lab1 = config.GetValue<string>(path + ":1:Label")

Now, I introduced a class ViewOption like so, with intention of mapping the config to an array of such elements.

public class ViewOption 
{
  public string Key { get; set; }
  public string Label { get; set; }
}

I was expecting that the following would work. Regrettably, it seems that the mapped value is null , so I guess the mapping fails recognizing the values.

ViewOption option0 = config.GetValue<ViewOption>(path + ":0")
List<ViewOption> options = config.GetValue<List<ViewOption>>(path)

What am I missing in the mapping?

My workaround is doing something like the below. However, it's ugly as duck and, also, I need to figure out the number of elements for the array separately, which is even uglier and duckier.

ViewOption option0 = new ViewOption(
  config.GetValue<string>(path + ":0:Key"),
  config.GetValue<string>(path + ":0:Label"));

If I understand it correctly the intention here is to use a custom type to represent a fragment of data from configuration.

Options Pattern was introduced to decouple custom settings from configuration API (such as IConfiguration ). An option normally binds to a section with a name representing that option instance. In your case it could be a class with GroupingOptions property:

public class MyViewOptions 
{
    public List<MyGroupingOption> GroupingOptions {get; set;}
}

public class MyGroupingOption
{
    public string Key {get; set;}
    public string Value {get; set;}
}

[...]

// Bind configuration sections to corresponding named options


public void ConfigureServices(IServiceCollection services)
{
    // Bind default (unnamed) option
    services.Configure<MyViewOptions>(Configuration.GetSection("ViewOptionsConfiguration:Default");   

    // Bind named options
    services.Configure<MyViewOptions>(Configuration.GetSection("ABC", "ViewOptionsConfiguration:ABC");   

    services.Configure<MyViewOptions>(Configuration.GetSection("DEF", "ViewOptionsConfiguration:DEF");   

}

Usage:

 // for default options only
 MyService(IOptions<MyViewOptions> options)
 {
    var opts = options.Value;
 }


 // for named (and default) options

 MyService(IOptionsSnapshot<MyViewOptions> options)
 {
      var defaultOptions = options.Value;
      var abcOptions = options.Get("ABC");
      var defOptions = options.Get("DEF");
 }

I think you are pretty much close. I have done something like below into.Net 5 targeted console app. I have posted my full answer for someone else on this link .

List<string> emailAddresses = _config.GetSection("EmailAddresses").Get<List<string>>();
        foreach (string emailAddress in emailAddresses)
        {

            Console.WriteLine(emailAddress);
        }

My appsettings.json is:

{
  "AppSettings": {

    "FTPLocation": "\\\\FTPHostname\\\\c$\\\\Folder\\\\ftpSite\\\\Prod\\",
    "FTPUri": "ftp://ftphostname/myFolder/",
    "CSVFileName": "TestData.csv",
    },
  "ConnectionStrings": {
    "AppDbConnString": "Server=sqlserverhost.domain.com;Database=DBName; Trusted_Connection=True; MultipleActiveResultSets=true"
    ,
"IdentityConnection": "Server=hostname.domain.com;Database=IdentityDBName; Trusted_Connection=True; MultipleActiveResultSets=true"
      },  
    "EmailAddresses": [
          "email1@test.com",
          "email2@test.com",
          "email3@test.com"
        ],  
      "Logging": {
        "LogLevel": {
          "Default": "Warning"
        }
      }
 }

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