【问题标题】:Getting an array of un-named json tuple from appsettings.json从 appsettings.json 获取一组未命名的 json 元组
【发布时间】:2021-11-05 02:14:40
【问题描述】:

在 appsettings.json 我有未命名的 json:

{
    "Items": [
        {"fruit": "apple"},
        {"fruit": "cherry"},
        {"fruit": "tomato"},
        {"vegetable": "carrot"},
        {"vegetable": "tomato"}
    ]
}

现在我想把它放在一个元组变量的列表或数组中。我正在寻找最简单的代码(可能是 .net core 2050 大声笑),例如:

public static readonly IConfiguration config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
...
var items = config.GetValue<(string,string)[]>("Items");
var items = config.GetValue<List<(string,string)>>("Items");

什么是简单的解决方案,因为上面的行不起作用。我正在寻找可以替换这部分的东西:“config.GetValue("Items");"

试过了:

(string,string)[] items = config.GetSection("Items")
  .GetChildren()
  .ToList()
  .Select(x => (x.Key,x.Value)).ToArray();
Console.WriteLine($"{items.Length}, {items[1]}"); // 2, (1, )
var items = config.GetValue<List<Dictionary<string,string>>>("Items"); // null

var items = config.GetValue<List<Tuple<string,string>>>("Items"); // null

var items = config.GetValue<List<KeyValuePair<string,string>>>("Items"); // null

var items = config.GetSection("Items")
  .GetChildren()
  .Select(x => new Tuple<string, string>(x.Key, x.Value));
foreach (var item in items) Console.WriteLine($"({item.Item1},{item.Item2})"); // (0,) (1,)

【问题讨论】:

  • 你试过字典而不是元组config.GetValue&lt;Dictionary&lt;string,string&gt;&gt;("Items");
  • 我试过 Dictionary,但没有成功。
  • 字典的问题是它只允许一个键一次。该示例包含多种水果和蔬菜。

标签: c# .net-core


【解决方案1】:

先使用Configuration.GetSection(string)获取Items键对应的值,然后从子值构造IEnumerable&lt;Tuple&lt;string,string&gt;&gt;

ConfigurationSection section = config.GetSection("Items");

var data = section
.GetChildren()
.Select(x => new Tuple<string, string>(x.Key, x.Value));

【讨论】:

  • 我已经尝试过这些解决方案。他们根本不工作。另外,我必须使用这个未命名(标签是可变的)json。
  • @AlainTrépanier 将您已经尝试过的内容包含在您的问题中会很有帮助,以帮助回答者避免提出对您不起作用的解决方案。请参阅 how to ask 了解更多有用的指南。
  • 您的所有建议都返回 null
  • public static readonly IConfiguration config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
  • 这不起作用
【解决方案2】:

要做你想做的事,你可以像这样使用“绑定”方法:

    private List<T> GetList<T>(string configSection)
    {
        var result = new List<T>();
        config.GetSection($"{configSection}").Bind(result);
        return result;
    }

你可以这样调用这个方法

GetList<Dictionary<string, string>>("Items");

你需要引用 nuget Microsoft.Extensions.Configuration.Binder

请注意,我将逻辑包装到了一个方法中……但是您可以直接使用代码,而无需像这样包装方法:

        var items= new List<Dictionary<string,string>>();
        config.GetSection("Items").Bind(result);

现在你得到的是一个字典列表。但这是因为你的 JSON 的“形状”。

可以像这样简化成一个字典:

{
    "Items":  {
           "Item1": "Content1",
           "Item2": "Content2"
        }    
}

然后调用这段代码:

        var items= new Dictionary<string, string>();
        config.GetSection("Items").Bind(result);

在我看来,获得单个字典的最后一个选项更好且更具可扩展性。

【讨论】:

  • @AlainTrépanier 如果此答案对您有帮助,请标记为正确答案。谢谢。
  • 不,你“不需要”一个元组数组。您可以将配置提供为 Dictionary&lt;string,List&lt;string&gt;&gt;
  • 它不能被简化为一个字典,因为我没有不同的键。
  • 字典的问题是它只允许一个键一次。该示例包含多种水果和蔬菜。
  • 在 VS 2019 中,一旦您有 2 个 Item1 条目,VS 已经在 appsettings json 中抱怨。但是可以在条目周围使用花括号,例如: {"Item1": "Content1"} 所以不要说您的解决方案不起作用。实际上是我选的那个:-)
【解决方案3】:

试试这个

List<KeyValuePair<string,string>> items = Configuration
            .GetSection("Items")
            .Get<Dictionary<string, string>[]>()
            .SelectMany(i => i)
            .ToList();

如何使用示例

foreach (var item in items) 
    Console.WriteLine($"({item.Key},{item.Value})");

             var item1=items[0];
             var item2=items[1];
            var item1Key = item1.Key;
            var item1Value = item1.Value;

或者你可以继续转换成字典

            var dict=items.ToDictionary(x => x.Key, x => x.Value);
            var item1 = dict["Item1"]; // = "Content1"
            var item2 = dict["Item2"]; // = "Content2"

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 2017-07-02
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
相关资源
最近更新 更多