Как разобрать объект JSON на C #, если я заранее не знаю ключ?

У меня есть данные JSON, которые выглядят так:

{ "910719": { "id": 910719, "type": "asdf", "ref_id": 7568 }, "910721": { "id": 910721, "type": "asdf", "ref_id": 7568 }, "910723": { "id": 910723, "type": "asdf", "ref_id": 7568 } } 

Как я могу разобрать это с помощью JSON.net? Я могу сначала сделать это:

 JObject jFoo = JObject.Parse(data); 

Мне нужно иметь возможность перебирать каждый объект в этом списке. Я хотел бы иметь возможность сделать что-то вроде этого:

 foreach (string ref_id in (string)jFoo["ref_id"]) {...} 

или

 foreach (JToken t in jFoo.Descendants()) { Console.WriteLine((string)t["ref_id"]); } 

но, конечно, это не сработает. Все примеры отлично работают, если вы знаете ключ при написании кода. Он ломается, когда вы заранее не знаете ключ.

Это выполнимо; это работает, но это не изящно. Я уверен, что есть лучший способ.

 var o = JObject.Parse(yourJsonString); foreach (JToken child in o.Children()) { foreach (JToken grandChild in child) { foreach (JToken grandGrandChild in grandChild) { var property = grandGrandChild as JProperty; if (property != null) { Console.WriteLine(property.Name + ":" + property.Value); } } } } 

Печать:

  ID: 910719
 Тип: ASDF
 ref_id: 7568
 ID: 910721
 Тип: ASDF
 ref_id: 7568
 ID: 910723
 Тип: ASDF
 ref_id: 7568 

Вы можете перебирать потомков простым запросом LINQ следующим образом:

 JObject jFoo = JObject.Parse(json); foreach (JObject obj in jFoo.Properties().Select(p => p.Value)) { Console.WriteLine("id: " + obj["id"]); Console.WriteLine("ref_id: " + obj["ref_id"]); } 

Аналогичным образом, если вы хотите получить только значения ref_id , вы можете получить следующие значения:

 foreach (string refId in jFoo.Properties().Select(p => p.Value["ref_id"])) { Console.WriteLine(refId); } 

Я использую Json.NET, и я быстро написал, где вы можете распечатать все ключи и соответствующие значения с помощью рекурсивного метода.

  var o = JObject.Parse(YourJsonString); getAllProperties(o); //call our recursive method 

Затем вы можете использовать этот рекурсивный метод для получения всех свойств и их значений

  void getAllProperties(JToken children) { foreach (JToken child in children.Children()) { var property = child as JProperty; if (property != null) { Console.WriteLine(property.Name + " " + property.Value);//print all of the values } getAllProperties(child); } } 

Вы рассматривали использование JavascriptSerializer?

вы можете попробовать сделать что-то вроде этого:

 JavaScriptSerializer serializer = new JavaScriptSerializer(); var foo = serializer.Deserialize>>(data); foreach(var item in foo) { Console.Writeln(item.Value["ref_id"]); } 

http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

Решение Konstantin будет работать, но если вы хотите, чтобы список Id делал то же самое, а вместо Console.Writeln () использовали следующие

 List list = new List(); JavaScriptSerializer serializer = new JavaScriptSerializer(); var foo = serializer.Deserialize>>(data); foreach(var item in foo) { list.Add(item.Value["ref_id"]); } 

Я нашел ответ TrueWill, но я хотел избежать foreach и попытаться получить простой цикл для работы ради скорости. Мои результаты были, безусловно, тем, что в лучшем случае можно было бы назвать уродливым. Здесь они на случай, если они полезны для всех. (Я ушел в WriteLine, чтобы быть в состоянии видеть вещи немного легче.)

Обратите внимание, что это не сработает для некоторых JSON и не является совершенно общим. Некоторые нулевые проверки могут быть выполнены лучше и т. Д.

  // NOW, DOING IT ALL AS A FOR LOOP... // a, b, c, d - for iterator counters. // j1, j2, j3, j4 - the JTokens to iterator over - each is a child of the previous // p, q, r, s - The properties from j1/2/3/4. JObject o = JObject.Parse(json); JToken j1 = o.First; for (int a = 0; a < o.Children().Count(); a++) { // Outermost loop gives us result, error, id. if (j1 == null) continue; if (a > 0) { j1 = j1.Next; if (j1 == null) continue; } var p = j1 as JProperty; Console.WriteLine("FOR 0 = " + a.ToString() + " --- " + p.Name); // DO STUFF HERE. // FIRST INNER LOOP // Set up a JToken or continue JToken j2 = j1.Children().First() as JToken; if (j1.Children().Count() > 0) { j2 = j1.Children().First() as JToken; } else { continue; } Console.WriteLine("*** STARTING FIRST INNER..."); for (int b = 0; b < j1.Children().Count(); b++) { // returns nothing as second loop above. if (j2 == null) { Console.WriteLine("*** j2 null 1..."); continue; } if (b > 0) { j2 = j2.Next; if (j2 == null) { Console.WriteLine("*** j2 null 2..."); continue; } } var q = j2 as JProperty; // These null checks need to be != or ==, depending on what's needed. if (q != null) { Console.WriteLine("FOR 1 = " + a.ToString() + "," + b.ToString() + " --- " + q.Name); // DO STUFF HERE. // ... } // q !null check // SECOND INNER LOOP // Set up a JToken or continue JToken j3; if (j2.Children().Count() > 0) { j3 = j2.Children().First() as JToken; } else { continue; } Console.WriteLine("****** STARTING SECOND INNER..."); for (int c = 0; c < j2.Children().Count(); c++) { if (j3 == null) continue; if (c > 0) { j3 = j3.Next; if (j3 == null) continue; } var r = j3 as JProperty; if (r == null) { continue; } // r null check Console.WriteLine("FOR 2 = " + a.ToString() + "," + b.ToString() + "," + c.ToString() + " --- " + r.Name); // DO STUFF HERE. // THIRD INNER LOOP // Set up a JToken or continue JToken j4; if (j3.Children().Count() > 0) { j4 = j3.Children().First() as JToken; } else { continue; } Console.WriteLine("********* STARTING THIRD INNER..."); for (int d = 0; d < j3.Children().Count(); d++) { if (j4 == null) continue; if (c > 0) { j4 = j4.Next; if (j4 == null) continue; } var s = j4 as JProperty; if (s == null) { continue; } // s null check Console.WriteLine("FOR 3 = " + a.ToString() + "," + b.ToString() + "," + c.ToString() + "," + d.ToString() + " --- " + s.Name); // DO STUFF HERE. // ... } // for d - j3 } // for c - j2 } // for b - j1 } // for a - original JObject 
  • Deserialize json с известными и неизвестными полями
  • Десериализация JSON с использованием JSon.NET с динамическими данными
  • C # WCF REST. Как вы используете сериализатор JSON.Net вместо стандартного DataContractSerializer?
  • Сериализация / десериализация пользовательской коллекции с дополнительными свойствами с помощью Json.Net
  • Как пропустить / игнорировать / пропускать пустые литералы объектов в выпуске JSON?
  • Json.Net - Сериализовать имя свойства без кавычек
  • Сериализация типа Json.Net с полиморфным дочерним объектом
  • Строка Parse Json в C #
  • Невозможно десериализовать текущий объект JSON (например, {"name": "value"}) в тип 'System.Collections.Generic.List`1
  • Не удалось загрузить файл или сборку «Newtonsoft.Json» или одну из его зависимостей. Определение манифеста не соответствует ссылке на сборку
  • Сериализовать контейнер перечислений в виде строк с помощью JSON.net
  • Давайте будем гением компьютера.