Как разобрать объект 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 
  • Как сериализовать словарь как часть его родительского объекта с помощью Json.Net
  • Как десериализовать дочерний объект с динамическими (числовыми) именами клавиш?
  • Преобразовать Newtonsoft.Json.Linq.JArray в список определенного типа объекта
  • JSON.net: как десериализовать без использования конструктора по умолчанию?
  • C # JSON.NET - десериализация ответа, использующего необычную структуру данных
  • Как преобразовать datatable в строку json с помощью json.net?
  • Как использовать Json.NET для JSON-моделирования в проекте MVC5?
  • Deserialize json, который имеет некоторое имя свойства, начиная с числа
  • Как программно выбирать конструктор во время десериализации?
  • JSON.NET как сериализатор OAP для WebAPI 2 и ODataMediaTypeFormatter
  • JsonValueProviderFactory выбрасывает «запрос слишком большой»
  • Interesting Posts

    Как автоматически генерировать файл classа C # из строки объекта JSON

    Sublime Text 2 – просмотр пробельных символов

    Ubuntu: ошибки в терминале: как показать их на английском языке?

    Использование fseek с указателем файла, указывающим на stdin

    Служба Windows, не показанная в приложении, удаляет программы под панелью управления

    Как включить / отключить чрезмерное сканирование на моем телевизоре в Catalyst Control Center?

    Как реализовать stream активности в социальной сети

    Проверьте, является ли число фибоначчи

    nodejs httprequest с данными – получение ошибки getaddrinfo ENOENT

    Физическая консоль (экран + клавиатура), предназначенная для виртуальной машины

    NetUIHWND и DirectUIHWND

    Установка VS2010 SP1. «Функция, которую вы пытаетесь использовать, находится на сетевом ресурсе, который недоступен»

    Многопроектные тестовые зависимости с gradleиентом

    Большие целые числа в C #

    Как инициализировать List для заданного размера (в отличие от емкости)?

    Давайте будем гением компьютера.