【问题标题】:How to convert a flat json object to a List of a strong type object如何将平面 json 对象转换为强类型对象列表
【发布时间】:2019-06-21 17:46:33
【问题描述】:

我有一个 Api,它返回一个像这样的 json 对象,我对此没有任何控制:

{  
 "name[0]":"cat",
 "map[0]":"catmap",
 "name[1]":"dog",
 "map[1]":"dogmap",
 "name[2]":"lion",
 "map[2]":"lionmap",
 "name[3]":"tiger",
 "map[3]":"tigermap",
 "name[4]":"snake",
 "map[4]":"snakemap"
}

(name[i], map[i])对的数量不限。

我需要将其转换为强对象列表:List

 public class Animal
 {
    public string Name { get; set; }
    public string Map { get; set; }
  }

我怎么可能?有什么想法吗?

【问题讨论】:

  • 你自己说的。有一堂课,里面有一个列表。并且每次都获取这个对象,循环遍历它,然后逐个赋值给列表。
  • 熟悉 Json.NET 库。使用它,您可以将 json 文件加载为 JObject(来自 Json.NET 库的类型),然后您可以查询其属性和相应的属性值。如果您愿意,甚至可以将 Linq 与它一起使用。 (Json.NET 文档以及 StackOverflow 上关于 Json.NET / JObject 的许多问题和答案可以告诉你更多关于它的细节)
  • @elgonzo 我们在这里提出问题以获得详细的答案,而不仅仅是链接到图书馆,如何开始回答,我会检查
  • 你是想告诉我你拒绝投入研究,由于你不愿意做研究,我应该为你做吗?如果不是,你到底想用你的评论告诉我什么?
  • @elgonzo 过去曾为他们数百次工作过,包括这次。如果他们清楚地知道不需要编程,为什么还要花时间学习编程?

标签: c# json


【解决方案1】:

这是一个使用 Json.Net 的 LINQ-to-JSON API 的整洁解决方案。

它的工作原理是按索引对属性进行分组,然后通过临时 JObject 将组转换为 Animal 对象。

var animals = (from p in JObject.Parse(json).Properties()
               let parts = p.Name.Split(new char[] { '[', ']' })
               group new JProperty(parts[0], p.Value) by int.Parse(parts[1]) into g
               orderby g.Key
               select new JObject(g).ToObject<Animal>())
               .ToList();

此解决方案的优点:

  • 不对属性名称进行硬编码:只要 JSON 属性名称与 Animal 类中的属性名称匹配(不区分大小写),代码就不会关心它们是什么。
  • 如果以后添加更多属性,它仍然可以工作。
  • 不要求给定动物的所有属性都存在。
  • 不依赖于 JSON 中属性的特定顺序。

工作演示:https://dotnetfiddle.net/WHnwAi

【讨论】:

  • 非常好的解决方案!
【解决方案2】:

不是最好的解决方案,但有效:

        var list = new List<Animal>();
        var r = JsonConvert.DeserializeObject<Dictionary<string, string>>(data).Values.ToArray();
        for (int i = 0; i < r.Length; i+=2)
        {
            list.Add(new Animal()
            {
                Name = r[i],
                Map = r[i+1]
            });
        }

【讨论】:

  • 请注意,字典不保证键/值的特定顺序。任何感知到的顺序只是巧合,在不同的 .NET 运行时/平台上运行代码时可能不会观察到相同的行为。因此,依赖 Dictionary.Values 集合的特定顺序是非常危险的......
【解决方案3】:

敢于提供正则表达式解决方案:

var animals = new List<Animal>();
var matches = Regex.Matches(json, @"(?s)""name\[\d+]"":.+?""map\[\d+]"":.+?(?=,|\r\n|})");
foreach (Match match in matches)
{
    var json_obj = $"{{{Regex.Replace(match.Value, @"\[\d+]", "")}}}";
    var animal = Newtonsoft.Json.JsonConvert.DeserializeObject<Animal>(json_obj) as Animal;
    animals.Add(animal);
}

【讨论】:

    【解决方案4】:

    同样,不是最好的解决方案,但给出了所需的结果:

    var json = "{  \r\n \"name[0]\":\"cat\",\r\n \"map[0]\":\"catmap\",\r\n \"name[1]\":\"dog\",\r\n \"map[1]\":\"dogmap\",\r\n \"name[2]\":\"lion\",\r\n \"map[2]\":\"lionmap\",\r\n \"name[3]\":\"tiger\",\r\n \"map[3]\":\"tigermap\",\r\n \"name[4]\":\"snake\",\r\n \"map[4]\":\"snakemap\"\r\n}";
    
    var jObject = JObject.Parse(json);
    
    var list = new List<Animal>();
    
    for (int i = 0; i < jObject.Count / 2; i++)
    {
        list.Add(new Animal
        {
            Name = jObject.GetValue($"name[{i}]").ToString(),
            Map = jObject.GetValue($"map[{i}]").ToString()
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 1970-01-01
      相关资源
      最近更新 更多