我有一个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; }
}
我该怎么办?有什么主意吗?
答案 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();
此解决方案的优点:
Animal
类中的属性名称匹配(不区分大小写),代码就不在乎它们是什么。正在运行的演示: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()
});
}