无法从 appsettings.json 的 IConfiguration 提供商映射实例

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

在我的appsettings.test.json中,我有以下结构。

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

然后,我可以使用以下语法读取它(获取正确的值)。

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")

现在,我像这样引入了一个 class ViewOption,目的是将配置映射到此类元素的数组。

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

我原以为以下内容会起作用。遗憾的是,映射的值似乎是null,所以我猜映射无法识别这些值。

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

我在映射中遗漏了什么?

我的解决方法是执行如下操作。然而,它丑得像鸭子,而且,我还需要单独计算出数组的元素数量,这更加丑陋和鸭子。

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

如果我理解正确的话,这里的目的是使用自定义类型来表示来自配置的数据片段。

引入

Options Pattern 是为了将自定义设置与配置 API(例如 IConfiguration)分离。一个选项通常绑定到一个名称代表该选项实例的部分。在您的情况下,它可能是 class 和 GroupingOptions 属性:

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

}

用法:

 // 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");
 }

我认为你非常接近。我在 .Net 5 目标控制台应用程序中做了类似下面的事情。我已经在 .

上为其他人发布了我的完整答案
List<string> emailAddresses = _config.GetSection("EmailAddresses").Get<List<string>>();
        foreach (string emailAddress in emailAddresses)
        {

            Console.WriteLine(emailAddress);
        }

我的appsettings.json是:

{
  "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"
        }
      }
 }