C# – Deserialize JSON to a dictionary

I’ll show examples of how to deserialize JSON to dictionaries in different scenarios.

Deserializing to Dictionary<string, string>

When your JSON object has properties with simple string values (as opposed to nested objects), you can deserialize to Dictionary<string, string>.

Here’s an example. Consider the following simple JSON object:

{
    "Name":"Bob",
    "Job":"Chef",
    "Location":"Seaside"
}Code language: JSON / JSON with Comments (json)

Note: In all examples, I’ll show the pretty-printed JSON string separately from the code like this for readability.

To deserialize this JSON object, use the built-in JsonSerializer.Deserialize() (in System.Text.Json) and specify Dictionary<string, string> as the target type, like this:

using System.Collections.Generic;
using System.Text.Json;

var dictionary = JsonSerializer.Deserialize<Dictionary<string, string>>(json);

foreach(var (key, val) in dictionary)
{
    Console.WriteLine($"{key}={val}");
}
Code language: C# (cs)

This loops through the dictionary and outputs the key/value pairs:

Name=Bob
Job=Chef
Location=SeasideCode language: plaintext (plaintext)

    Deserializing a nested object to a dictionary

    When your JSON object has properties with nested objects, you can either:

    • Deserialize to Dictionary<string, class>.
    • Deserialize to a nested dictionary.

    I’ll show examples below.

    Deserialize to Dictionary<string, class>

    Let’s say you have the following JSON object containing a nested object:

    {
      "ABC": {
        "Name": "Bob",
        "Age": 40
      },
      "DEF": {
        "Name": "Teddy",
        "Age": 45
      }
    }Code language: JSON / JSON with Comments (json)

    If possible, create a class for the nested object. In this example, I created a Person class matching the nested object properties (Name and Age):

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    Code language: C# (cs)

    Then you can deserialize to Dictionary<string, Person>, like this:

    using System.Collections.Generic;
    using System.Text.Json;
    
    var dictionary = JsonSerializer.Deserialize<Dictionary<string, Person>>(json);
    
    foreach (var (key, val) in dictionary)
    {
        Console.WriteLine($"{key}={val.Name}");
    }
    Code language: C# (cs)

    This outputs the following:

    ABC=Bob
    DEF=TeddyCode language: plaintext (plaintext)

    Deserialize to a nested dictionary

    If you don’t want to (or can’t) create a class for the nested object, you can deserialize to a nested dictionary. Consider the following JSON with nested objects:

    {
      "ABC": {
        "Name": "Bob",
        "Age": "40"
      },
      "DEF": {
        "Type": "Cat",
        "Sound": "Meow"
      }
    }Code language: JSON / JSON with Comments (json)

    Deserialize this with JsonSerializer.Deserialize() and specify a dictionary with nested dictionaries as the target type (Dictionary<string, Dictionary<string, string>), like this:

    using System.Collections.Generic;
    using System.Text.Json;
    
    var dictionary = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, string>>>(json);
    
    foreach (var (key, nestedDictionary) in dictionary)
    {
        Console.WriteLine(key);
        foreach(var (property, val) in nestedDictionary)
        {
            Console.WriteLine($"\t{property}={val}");
        }
    }
    Code language: C# (cs)

    This loops through the dictionary and its nested dictionaries and outputs the following:

    ABC
            Name=Bob
            Age=40
    DEF
            Type=Cat
            Sound=MeowCode language: plaintext (plaintext)

    Deserializing to Dictionary<string, object>

    Let’s say you have a JSON object containing properties with a mix of value types (such as string and int). First, I strongly recommend creating a class matching the JSON structure in this case. If you can’t do that, then one option is to deserialize to Dictionary<string, object> with Newtonsoft (or deserialize to a dynamic object).

    Consider the following JSON with mixed value types (string, int, bool):

    {
      "Name":"Bob",
      "Id":100,
      "IsCat":true
    }Code language: JSON / JSON with Comments (json)

    Use Newtonsoft (instead of System.Text.Json) to deserialize this to Dictionary<string, object>, like this:

    using System.Collections.Generic;
    using Newtonsoft.Json;
    
    var dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
    
    foreach (var (key, val) in dictionary)
    {
        Console.WriteLine($"Key={key} Value={val} Type={val.GetType().Name}");
    }
    Code language: C# (cs)

    This outputs the following.

    Key=Name Value=Bob Type=String
    Key=Id Value=100 Type=Int64
    Key=IsCat Value=True Type=BooleanCode language: plaintext (plaintext)

    The reason to use Newtonsoft here is because it deserializes to the expected object types (notice it output String, Int64, and Boolean). Compare this with System.Text.Json, which outputs Dictionary<string, JsonElement> and requires extra effort on your part to get the actual underlying values.

    If you have an even more complex scenario (such as a mix of simple and nested object properties), consider writing a custom JSON converter or parsing with JsonDocument.

    Leave a Comment