8

EDIT: I figured out how to get each key, now the problem is looping through each collection. Solution at bottom!

I'm trying to parse a JSON payload that has the following format:

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

I don't need the version key, so I'm ignoring it while coding my classes. This is what I have so far:

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

I've checked around StackOverflow and I've seen people using Dictionary<int, string> for similar problems, but it doesn't look like people have each JSON object in the root. I'm using JSON.net to parse everything.

In PHP, I could easily use json_decode() and walk through the array and extract all the info I need, but I'm stumped by C#.

EDIT: Solution begins below.

I looked at the JSON.net documentation and they used dictionaries, so I tried using nested dictionaries, and it seems to work!

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

And I can access the artist and title properties via:

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

respectively.

This eliminates the need for pre-built classes. Now I'm having trouble looping through each set of data collection (e.g. artist and title info for song[1], song[2], song[3], ..., song[n]).

3
  • Can't you foreach on the dictionary keys like so : foreach(var key in songs.Keys) { var song = songs[key]; } ? Commented Nov 21, 2013 at 4:25
  • If you've solved the problem, please post your solution as an answer and (once allowed to) accept it. That will mark this question as solved for future users of the site. Thanks! Commented Nov 21, 2013 at 16:51
  • I think you're going to have trouble with the "version" key if you try to deserialize into dictionaries. I've added an answer with an alternative approach. Commented Nov 21, 2013 at 16:59

1 Answer 1

5

If you try to deserialize into a Dictionary<int, Dictionary<string, string>> with the above JSON you're going to run into problems with the version key because it does not fit the data format for the dictionaries (version is not an int, and 1.1 is not a Dictionary<string, string>). I know you said you're "ignoring it for now", but that implies that it will be there in the future, so you need to handle it.

If you don't want to have pre-defined classes, then you're better off using Json.Net's LINQ-to-JSON API to work with the data. Here is how you can get the data you want using this approach:

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"]);
        }
    }
}

Output:

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

There are many other samples to be found in the documentation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.