2013-11-21 1 views
3

EDIT: Я выяснил, как получить каждый ключ, теперь проблема перебирает каждую коллекцию. Решение внизу!Deserializing JSON с цифрами как ключи

Я пытаюсь разобрать JSON полезную нагрузку, которая имеет следующий формат:

{ 
    "version": "1.1", 
    "0": { 
       "artist": "Artist 1", 
       "title": "Title 1" 
     }, 
    "1": { 
       "artist": "Artist 2", 
       "title": "Title 2" 
     }, 
    ... 
    "29": { 
       "artist": "Artist 30", 
       "title": "Title 30" 
     } 
} 

мне не нужен ключ version, поэтому я игнорирую его при кодировании моих классов. Это то, что я до сих пор:

public class Song 
{ 
    public string artist { get; set; } 
    public string title { get; set; } 
} 

Я проверил вокруг StackOverflow, и я видел людей, использующих Dictionary<int, string> для подобных проблем, но он не похож на людей каждый объект JSON в корне. Я использую JSON.net для анализа всего.

В PHP я мог бы легко использовать json_decode() и пройти через массив и извлечь всю необходимую информацию, но я в тупике от C#.

EDIT: Решение начинается ниже.

Я смотрел документацию JSON.net, и они использовали словари, поэтому я попытался использовать вложенные словари, и, похоже, это сработало!

Dictionary<int, Dictionary<string, string>> song = JsonConvert.DeserializeObject<Dictionary<int, Dictionary<string, string>>>(json); 

И я могу получить доступ к artist и title свойства с помощью:

song[0]["artist"] 
song[0]["title"] 

соответственно.

Это устраняет необходимость в заранее подготовленных классах. Теперь у меня возникают проблемы с циклом каждого набора данных (например, артист и информация о названии для песни [1], песни [2], песни [3], ..., песни [n]).

+0

Не можете ли вы использовать ключи словаря так: foreach (var key in songs.Keys) {var song = songs [key]; }? – atomaras

+0

Если вы решили проблему, отправьте свое решение в качестве ответа и (однажды разрешите) принять его. Это будет означать этот вопрос, который будет разрешен для будущих пользователей сайта. Благодаря! –

+0

Я думаю, что у вас возникнут проблемы с ключом «версия», если вы попытаетесь десериализовать словари. Я добавил ответ с альтернативным подходом. –

ответ

2

При попытке десериализации в Dictionary<int, Dictionary<string, string>> с выше JSON вы собираетесь столкнуться с проблемами с ключом version, потому что он не вписывается в формат данных для словарей (version не является int и 1.1 не a Dictionary<string, string>). Я знаю, что вы сказали, что сейчас «игнорируете это», но это означает, что он будет в будущем, поэтому вам нужно будет справиться с этим.

Если вы не хотите иметь предварительно определенные классы, то вам лучше использовать Json.Net's LINQ-to-JSON API для работы с данными. Вот как вы можете получить данные, которые вы хотите использовать этот подход:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string json = @" 
     { 
      ""version"": ""1.1"", 
      ""0"": { 
         ""artist"": ""Artist 1"", 
         ""title"": ""Title 1"" 
       }, 
      ""1"": { 
         ""artist"": ""Artist 2"", 
         ""title"": ""Title 2"" 
       }, 
      ""29"": { 
         ""artist"": ""Artist 30"", 
         ""title"": ""Title 30"" 
       } 
     }"; 

     JObject songs = JObject.Parse(json); 

     foreach (JProperty song in songs.Properties()) 
     { 
      if (song.Name == "version") continue; // skip "version" property 
      Console.WriteLine("Song " + song.Name + " artist: " + song.Value["artist"]); 
      Console.WriteLine("Song " + song.Name + " title: " + song.Value["title"]); 
     } 
    } 
} 

Выход:

Song 0 artist: Artist 1 
Song 0 title: Title 1 
Song 1 artist: Artist 2 
Song 1 title: Title 2 
Song 29 artist: Artist 30 
Song 29 title: Title 30 

Есть много других образцов можно найти в documentation.