C# 如何使用json.NET反序列化动态命名的根节点
这是json文件的一个示例:C# 如何使用json.NET反序列化动态命名的根节点,c#,json.net,deserialization,C#,Json.net,Deserialization,这是json文件的一个示例: { "John Smith": { "id": "72389", "email": "johnsmith@gmail.com", "books": [ { "id": "0", "title": "The Hunger Games", "rating": "5" }, { "i
{
"John Smith": {
"id": "72389",
"email": "johnsmith@gmail.com",
"books": [
{
"id": "0",
"title": "The Hunger Games",
"rating": "5"
},
{
"id": "1",
"title": "Harry Potter and the Order of the Phoenix",
"rating": "3"
},
],
"magazines": [
{
"id": "2",
"title": "National Geographic",
"rating": "1"
},
{
"id": "3",
"title": "Wired",
"rating": "4"
}
],
}
}
注意,根节点有一个动态名称(John Smith),我需要反序列化的每个json都有一个不同的名称。
此json结构需要按如下方式设置类:
public class RootObject
{
public JohnSmith { get; set; }
}
public class JohnSmith //oops
{
public string id { get; set; }
public string email { get; set; }
public List<Book> books { get; set; }
public List<Magazine> magazines { get; set; }
}
public class Book
{
public string id { get; set; }
public string title { get; set; }
public string rating { get; set; }
}
public class Magazine
{
public string id { get; set; }
public string title { get; set; }
public string rating { get; set; }
}
公共类根对象
{
公共JohnSmith{get;set;}
}
公共类JohnSmith//oops
{
公共字符串id{get;set;}
公共字符串电子邮件{get;set;}
公共列表书籍{get;set;}
公共列表杂志{get;set;}
}
公共课堂用书
{
公共字符串id{get;set;}
公共字符串标题{get;set;}
公共字符串评级{get;set;}
}
公共类杂志
{
公共字符串id{get;set;}
公共字符串标题{get;set;}
公共字符串评级{get;set;}
}
我的目标是反序列化“绕过/忽略”根对象,最重要的是动态命名节点。这并不重要,但我希望能够获取姓氏并将其设置为Person类的属性
public class Person
{
public string id { get; set; }
public string email { get; set; }
public string name { get; set; }
public List<Book> books { get; set; }
public List<Magazine> magazines { get; set; }
}
public class Book
{
public string id { get; set; }
public string title { get; set; }
public string rating { get; set; }
}
public class Magazine
{
public string id { get; set; }
public string title { get; set; }
public string rating { get; set; }
}
公共类人物
{
公共字符串id{get;set;}
公共字符串电子邮件{get;set;}
公共字符串名称{get;set;}
公共列表书籍{get;set;}
公共列表杂志{get;set;}
}
公共课堂用书
{
公共字符串id{get;set;}
公共字符串标题{get;set;}
公共字符串评级{get;set;}
}
公共类杂志
{
公共字符串id{get;set;}
公共字符串标题{get;set;}
公共字符串评级{get;set;}
}
我现在是这样做的:
var jo = JObject.Parse(json);
var deserializable = jo.First.First.ToString();
string name;
var jp = (JProperty)jo.First;
if (jp != null) name = jp.Name;
var person = JsonConvert.DeserializeObject<Person>(deserializable);
person.name = name;
var jo=JObject.Parse(json);
var deserializable=jo.First.First.ToString();
字符串名;
var jp=(JProperty)jo.First;
如果(jp!=null)name=jp.name;
var person=JsonConvert.DeserializeObject(可反序列化);
person.name=姓名;
这工作正常,但我想知道,也许使用自定义JsonConverter可以做得更好?恐怕这有点超出我的能力范围,所以我想在这里寻求帮助
无论如何,如果有更好的方法来实现这一点,请分享。我会先尝试在原始JSON上使用正则表达式,提取名称,用固定节点名称替换正则表达式,然后使用您现在知道的根节点对修改后的结果调用反序列化。我会保留解决方案的第一部分(反序列化到
JObject
),但我不会再进行另一次序列化。我的代码如下所示:
var jo = JObject.Parse(json);
var jp = jo.Properties().First();
var name = jp.Name;
var person = jp.Value.ToObject<Person>();
[JsonConverter(typeof(PersonListConverter))]
class PersonList
{
public List<Person> Persons { get; set; }
}
其中个人列表
如下所示:
var jo = JObject.Parse(json);
var jp = jo.Properties().First();
var name = jp.Name;
var person = jp.Value.ToObject<Person>();
[JsonConverter(typeof(PersonListConverter))]
class PersonList
{
public List<Person> Persons { get; set; }
}
[JsonConverter(typeof(PersonListConverter))]
阶级人格主义者
{
公共列表人员{get;set;}
}
如何获取主属性的名称?@RoyiNamir我不确定您想知道什么。您想准确获取哪个属性的名称?cryodream的JSON示例只有一个人(=主对象中的一个属性)。我的代码迭代主对象的所有属性。但是使用示例JSON,当然只有一次迭代。因此,在我的代码中没有主属性。根对象的所有属性都被视为相同的(在foreach
循环中)。我指的是var jo=JObject.Parse(JSON);
如何获取通过jo
“john Smith”?如果你知道名字,你可以通过jo[“john Smith”]
访问它。如果你不知道名字,你必须迭代所有属性,比如我的代码中ReadJson
方法的foreach
循环中的属性。prop.name
就是“john Smith”“
。您可以在此处阅读关于LINQ到JSON的文档: