Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用json.NET反序列化动态命名的根节点_C#_Json.net_Deserialization - Fatal编程技术网

C# 如何使用json.NET反序列化动态命名的根节点

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

这是json文件的一个示例:

{
   "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的文档: