configuration.GetValue列表返回null

时间:2017-12-15 12:42:40

标签: c# .net .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; }
}

和我的appsettings.json

{
"Connections": [
    {
      "Name": "",
      "Host": "192.168.1.5",
      "Account": "74687",
      "Password": "asdsdadsq"
    },
    {
      "Name": "",
      "Host": "127.0.0.1",
      "Account": "45654",
      "Password": "asdasads"
    }
  ]
}

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

5 个答案:

答案 0 :(得分:3)

根据the documentation for GetValue<>,它获取(单个)密钥的值并将其转换为指定的类型。不幸的是,如果无法转换该值,则不会抛出错误,这就是您遇到的情况。

我相信在你的情况下Get<>会更好。

var rr = configuration.GetSection("Connections").Get<IList<ConnectionSettings>>();

根据Get<>'s documentation,它:

  

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

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

另一种选择是@AthanasiosKataras说;使用Bind<>。当您可能具有稀疏配置时,如果要使用默认值或计算值覆盖某些值,这将非常有用。

答案 1 :(得分:2)

我在github上发现了以下内容:GetValue not working with lists

长话短说:这是设计上的。

所以你可以试试这个:

var result = new List<ConnectionSettings>();
var rr = configuration.GetSection("Connections").Bind(result);

答案 2 :(得分:1)

如果您是从头开始开发项目的,即使用VS模板,则为appsettings.json设置以下属性(右键单击appsettings.json->单击Properties )。之后,更新以下属性值。

复制到输出目录:始终复制

现在,您可以运行应用程序并使用GetValue方法获取价值。

此后,您可以恢复与以前相同的设置

复制到输出目录:如果较新则复制

答案 3 :(得分:0)

当使用非原始结构(例如列表或数组)进行嵌套配置时,

Configuration.Get是更好的选择。

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

或使用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;
        }
    }

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

答案 4 :(得分:0)

这可能对您有用。

GetValue<type>("key")不适用于复杂类型。

假设您具有以下appsettings.json结构:

{
    "ArrayOfObjectsWithinObjects": [
        {
            "foo0": "bar",
            "foo1": 1,
            "foo2": false,
            "anotherObject": {
                "foo3.1": "3.1",
                "foo3.2": "3.2"
            }
        },
        {
            "foo0": "bar",
            "foo1": 1,
            "foo2": false,
            "anotherObject": {
                "foo3.1": "3.1",
                "foo3.2": "3.2"
            }
        }
        ...

    ]

}

和C#适当的类

public class Foo
    {
        public string foo0 { get; set;}
        public int foo1 { get; set;}
        public bool foo2 { get; set;}
        public AnotherObject anotherObject { get; set;}
    }

 public class AnotherObject
    {
        public string foo3.1 { get; set; }
        public string foo3.2 { get; set; }
    }

您应该能够:

//using static System.Console;
//using System.Linq;
//using Microsoft.Extensions.Configuration;

   var _listOfFoos =  _config.GetSection("ArrayOfObjects")
                        .GetChildren()
                        .ToList()
                        .Select( x => new Foo
                                      {
                                         x.GetValue<string>("")
                                         x.GetValue<int>("")
                                         x.GetValue<bool>("")
                         x.GetSection("anotherObject").Get<AnotherObject>()                       
                                        });

        WriteLine(_listOfFoos.anotherObject.foo3.1);

请注意,foo3.1是无效的c#语法,用于教学目的。