Dynamic JSON with Json.NET

Tags: .NET, C#

With the release of .NET 4.0 we can use dynamic feature when serializing/deserializing objects using JSON.NET. In this article I give examples how to use dynamic parsing of JSON object and extract only the information you need.

Let's say we have this JSON but we need to deserialize only the image part and not the entire object - we need to access the path widget.web.image. Without using dynamic parsing we’ll need to use JToken and implement some intermediate steps.

 

{
  "widget": {
    "debug": "on",
    "window": {
      "title": "A window",
      "name": "window",
      "width": 250,
      "height": 100
    },
    "web": {
      "image": {
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 200,
        "alignment": "center"
      }
    },
    "text": {
      "data": "User Info",
      "size": 6,
      "style": "bold",
      "name": "info",
      "hOffset": 20,
      "vOffset": 10,
    }
  }
}

The widget.web.image will be deserialized in this Image class

public class Image
public string Src { get; set; }
    public string Name { get; set; }
    public int HOffset { get; set; }
    public int VOffset { get; set; }
    public string Alignment { get; set; }
}

 

This code will deserialize only the image. The dynamic helps to create the path to the image.

public static Image Parse(string json)
{
    dynamic jsonObject = JsonConvert.DeserializeObject<dynamic>(json);
    dynamic imageObject = jsonObject.widget.web.image;

    return JsonConvert.DeserializeObject<Image>(imageObject.ToString());
}

As you can see the imageObject contains only the JSON of the image part.

 

In the above example the Image class has properties which match to JSON properties. Let's see an example where the properties don't match. Also instead of one image object will have an array of images.

This is the JSON object which contains an array of images.

{
  "widget": {
    "debug": "on",
    "window": {
      "title": "A window",
      "name": "window",
      "width": 250,
      "height": 100
    },
    "web": {
      "image": [ {
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 200,
        "alignment": "center"
      },{
	  "src": "Images/Clouds.png",
        "name": "clouds",
        "hOffset": 250,
        "vOffset": 200,
        "alignment": "center"
      }]
    },
    "text": {
      "data": "User Info",
      "size": 6,
      "style": "bold",
      "name": "info",
      "hOffset": 20,
      "vOffset": 10,
    }
  }
}

And the corresponding C# class:

public class NewImage
{
    public string Source { get; set; }
    public string ImageName { get; set; }
}

 

Here how we do the dynamic parsing.

public static NewImage[] Parse(string json)
{
    dynamic jsonObject = JsonConvert.DeserializeObject<dynamic>(json);

    var images = new List<NewImage>();

    foreach (dynamic imgObject in jsonObject.widget.web.image)
    {
        dynamic image = JValue.Parse(imgObject.ToString());

        images.Add(
            new NewImage
                {
                    ImageName = image.name,
                    Source = image.src
                }
            );
    }

    return images.ToArray();
}

 

We iterate through all the images and create dynamic object for each image.

The iteration loop is needed because the JSON properties and C# properties don’t match.

If they did match then the following will deserialize the JSON directly to NewImage collection.

 

JsonConvert.DeserializeObject<NewImage[]>(jsonObject.widget.web.image)

The source code can be found here https://github.com/ralbu/DynamicJson

Comments

comments powered by Disqus