configuration.GetValue列表返回null

pan*_*nis 7 .net c# .net-core

我正在尝试使用以下GetValue<T>方法从appsettings.json文件中读取列表:

var builder = new ConfigurationBuilder().SetBasePath(System.AppContext.BaseDirectory)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

IConfigurationRoot configuration = builder.Build();
var rr = configuration.GetValue<IList<ConnectionSettings>>("Connections");


public class ConnectionSettings
{
    public string Name { get; set; }

    public string Host { get; set; }

    public string Account { get; set; }

    public string Password { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和我的appsettings.json

{
"Connections": [
    {
      "Name": "",
      "Host": "192.168.1.5",
      "Account": "74687",
      "Password": "asdsdadsq"
    },
    {
      "Name": "",
      "Host": "127.0.0.1",
      "Account": "45654",
      "Password": "asdasads"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

问题是我总是空值,我不明白为什么。

小智 10

Configuration.Get<T> 当您使用非原始结构(如列表或数组)进行嵌套配置时,这是一个更好的选择。

{
  "Email": {
    "ToEmails": [
      "test1@test.com",
      "test2@test.com",
      "test3@test.com"
    ]
}

List<string> emailTo = _config.GetSection("Email:ToEmails").Get<List<string>>()

foreach (string email in emailTo)
{
    sendGridMessage.AddTo(new EmailAddress(email));
}
Run Code Online (Sandbox Code Playgroud)

或使用 Bind()

public static class ConfigurationRootExtentions
{
    public static List<T> GetListValue<T>(this IConfigurationRoot configurationRoot, string section)
    {
        var result = new List<T>();
        configurationRoot.GetSection(section).Bind(result);
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

参考[1]:https : //blog.bitscry.com/2017/11/14/reading-lists-from-appsettings-json/
参考[2]:https : //github.com/aspnet/Configuration/issues/ 451


Ath*_*ras 5

我在github上发现了以下内容:GetValue无法使用列表

长话短说:这是设计使然。

因此,您可以尝试以下操作:

var result = new List<ConnectionSettings>();
var rr = configuration.GetSection("Connections").Bind(result);
Run Code Online (Sandbox Code Playgroud)

  • 说真的为什么他们没有实施它???:) 我想避免绑定解决方案,但无论如何。 (4认同)

Mat*_*rey 5

根据的文档GetValue<>,它获取(单个)键的值并将其转换为指定的类型。不幸的是,如果无法转换该值,它不会引发错误,这就是您遇到的情况。

我认为这Get<>在您的情况下会更好。

var rr = configuration.GetSection("Connections").Get<IList<ConnectionSettings>>();
Run Code Online (Sandbox Code Playgroud)

根据Get<>的文档,它:

尝试将配置实例绑定到类型T的新实例。如果此配置节具有值,将使用该值。否则,通过将属性名称与配置键匹配来进行绑定。

这使您可以直接获取值,或者,如果找不到该属性,它将查找包含匹配属性的嵌套对象。

就像@AthanasiosKataras所说的那样。使用Bind<>。当您可能需要使用默认值或计算值覆盖一些值的稀疏配置时,这很有用。