简而言之,我的问题:我需要将两个大的JSON字符串反序列化为一个类,但字符串几乎没有什么不同。 这是第一个:
{
"persons": [
{
"age":30,
"name":"david",
"hobbies": [
{
"name":"tennis",
"hours":5
},
{
"name":"football",
"hours":10
}
]
},
{
"name":"adam",
"age":23,
"hobbies":[]
}
]
}
另一个:
{
"person": [
{
"age":25,
"name":"dave",
"hobbies":[
{
"name":"Basketball",
"hours":5
},
{
"name":"football",
"hours":10
}
]
},
{
"name":"Steve",
"age":28,
"hobbies": []
}
]
}
你可以看到一次是"人",另一次是"人"。有没有简单的解决方案?我正在考虑在我的班级中创建两个列表
List<Person> person;
List<Person> persons;
并在反序列化后以某种方式手动组合。但必须有一种更简单的方法。
顺便说一句,这不是我需要反序列化的确切代码。我只是想让主要思想尽可能简单。
一个简单的解决方案是在类中使用单个列表,然后添加一个具有引用相同列表的另一个名称的备用 setter。 您甚至可以将其设为私有,只要您用 [JsonProperty]
属性装饰它。 这样,类的公共接口看起来很正常,但它仍然可以同时使用两个 JSON 属性名称。
public class RootObject
{
[JsonProperty("persons")]
public List<Person> People { get; set; }
// This is visible to Json.Net and references the real list
[JsonProperty("person")]
private List<Person> Person
{
set { People = value; }
}
}
public class Person
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("age")]
public int Age { get; set; }
[JsonProperty("hobbies")]
public List<Hobby> Hobbies { get; set; }
}
public class Hobby
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("hours")]
public int Hours { get; set; }
}
小提琴:https://dotnetfiddle.net/9Dw48J
编辑
要解决您的意见:PopulateObject
可用于使用来自 JSON 的数据盲目地扩充现有对象,但它不会执行您正在寻找的那种合并。 你似乎正在寻找一种方法来匹配人们的名字(也许是年龄?),然后结合这些人的爱好。 为此,您需要编写自己的逻辑。 我建议将每个列表反序列化为RootObject
类的单独实例,然后在后处理步骤中合并数据。 您可以在RootObject
类上创建一个方法,该方法将接受另一个要合并RootObject
。 也许是这样的:
public class RootObject
{
...
public void MergeWith(RootObject other)
{
if (other.People == null) return;
if (People == null) People = new List<Person>();
foreach (Person person in other.People)
{
// You may need to make changes here--
// How do you determine whether two people are the same?
Person existingPerson = People.FirstOrDefault(p => p.Name == person.Name &&
p.Age == person.Age);
if (existingPerson != null)
{
existingPerson.MergeWith(person);
}
else
{
People.Add(person);
}
}
}
}
而在Person
课上...
public class Person
{
...
public void MergeWith(Person other)
{
if (other.Hobbies == null) return;
if (Hobbies == null) Hobbies = new List<Hobby>();
foreach (Hobby hobby in other.Hobbies)
{
Hobby existingHobby = Hobbies.FirstOrDefault(h => h.Name == hobby.Name);
if (existingHobby != null)
{
// You may need to make changes here--
// What do you do if two hobbies have the same name but different hours?
existingHobby.Hours += hobby.Hours;
}
else
{
Hobbies.Add(hobby);
}
}
}
}
要反序列化和合并,您需要执行以下操作:
var firstObj = JsonConvert.DeserializeObject<RootObject>(firstJson);
var secondObj = JsonConvert.DeserializeObject<RootObject>(secondJson);
firstObj.MergeWith(secondObj);
小提琴:https://dotnetfiddle.net/8Fiwsd
两者都包含一个List<Person>
。像往常一样将它们反序列化为两个类,但只需获取每个类具有的列表并将它们添加到同一列表中,因为它们包含相同的信息。
"不同的"字符串传递到不同的JObject
中。 然后通过不同的名称从这两个内部集合中获取(JObject
允许这样做),然后将这些集合反序列化为具有一个公共 C# 类的集合。
它看起来像从反序列化部分 JSON 区域,所以,你可以看看这个链接。