Search code examples
c#jsonjson.netdeserialization

C# Json To Dictionary of Objects


I want to take some Json and parse it in to a collection of key/value pairs, but some of the values will be dictionaries themselves. I tried the usual Newtonsoft deserialization. It's close, but not quite right. The end result must be a dictionary, not a strongly typed class.

This is some example Json:

{
  "JobNumber": 1010,
  "Asset": null,
  "JobNotes": [
    {
      "NoteText": "It's not working.",
      "NoteType": "Complaint"
    },
    {
      "NoteText": "Needs to be fixed",
      "NoteType": "Job"
    }
  ]
}

This is the code I used to deserialize:

        var json = File.ReadAllText(@"c:\temp\job.json");
        var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);

The result is almost correct, but the value of the item with a key of "JobNotes" is just json string. I want the parser to recurse in and deserialise the inner Json to a further dictionary of strings and objects. Is there a way I can do this with the Newtonsoft library? Or, is there another library that will do the trick? Can I hook in to the parsing method to override the functionality at that point in time?


Solution

  • This is a modified version of @DanielKeogh's code. It works well.

    class Program
    {
        static void Main(string[] args)
        {
            var json = File.ReadAllText(@"c:\temp\job3.json");
            var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
            RecurseDeserialize(result);
        }
    
        private static void RecurseDeserialize(Dictionary<string, object> result)
        {
            //Iterate throgh key/value pairs
            foreach (var keyValuePair in result.ToArray())
            {
                //Check to see if Newtonsoft thinks this is a JArray
                var jarray = keyValuePair.Value as JArray;
    
                if (jarray != null)
                {
                    //We have a JArray
    
                    //Convert JArray back to json and deserialize to a list of dictionaries
                    var dictionaries = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jarray.ToString()); 
    
                    //Set the result as the dictionary
                    result[keyValuePair.Key] = dictionaries;
    
                    //Iterate throught the dictionaries
                    foreach (var dictionary in dictionaries)
                    {
                        //Recurse
                        RecurseDeserialize(dictionary);
                    }
                }
            }
        }
    }
    

    This modified Json shows how deep it goes:

    {
      "JobNumber": 1010,
      "Asset": null,
      "JobNotes": [
        {
          "NoteText": "It's not working.",
          "NoteType": "Complaint"
        },
        {
          "NoteText": "Needs to be fixed",
          "NoteType": "Job",
          "JobNoteNotes": [
            {
              "Something": 1,
              "Something2": "Test"
            }
          ]
        }
      ]
    }
    

    The result ends three dictionaries deep so that I can get at the "Something" value by key.