如何将平面json对象转换为强类型对象的列表

时间:2019-06-21 17:46:33

标签: c# json

我有一个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"
}

(名称[i],地图[i])对的数量不受限制。

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

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

我该怎么办?有什么主意吗?

4 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

不是最好的解决方案,但是可以解决:

        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]
            });
        }

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

同样,不是最好的解决方案,但是会提供所需的结果:

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()
    });
}