Skip to main content
Email Password   helpLost your password?

Parsing Arbitrary JSON in .NET Code

One of the emerging popular formats for sharing content online is JSON, shorthand for JavaScript Object Notation. Intended to be slightly more efficient than XML, it's found a home in lots of AJAX powered web applications. Some companies actually require you talk to their APIs in terms of JSON too, so having the ability to parse and emit arbitrary JSON in a strongly typed way is a valuable tool to have. As of .NET 3.5 SP1, we are equipped with the DataContractJsonSerializer.

This tutorial will show you how to take an arbitrary piece of JSON and convert it into an object. Let's take a feed from the popular Flikr photo sharing site. Taking the latest public photos feed, you might get JSON such as:

jsonFlickrFeed({
    "title": "Uploads from everyone",
    "link": "http://www.flickr.com/photos/",
    "description": "",
    "modified": "2009-02-04T07:24:51Z",
    "generator": "http://www.flickr.com/",
    "items": [
            {
            "title": "Ohayo2009-224",
            "link": "http://www.flickr.com/photos/14427733@N07/3252849052/",
            "media": {
                "m":"http://farm4.static.flickr.com/3534/3252849052_ab77f0e3af_m.jpg"
            },            
            "date_taken": "2009-01-29T16:47:42-08:00",            
            "description": "Description of photo appears here",
            "published": "2009-02-04T07:24:51Z",
            "author": "Author of photos appears here",
            "author_id": "14420000@N00",
            "tags": "2009 ohayo"
        },
        .. more items
    ]
})

Break the Data into Objects

The trick now is to try and map the data structure into a set of .NET objects, and map each property on our objects to a field from the feed using the DataMember attribute. The classes themselves will be annotated with the DataContract attribute. Let's look at how we might do this for an 'item' from the Flikr feed we're using:

[DataContract()]
public class FlikrItem : IExtensibleDataObject 
{
    [DataMember(Name="title")]
    public String Title { get; set; }

    [DataMember(Name = "link", IsRequired = true)]
    public String Link { get; set; }

    [DataMember(Name="media")]
    public FlikrMedia Media { get; set; }

    // WCF stores any items we did not map here
    public ExtensionDataObject ExtensionData { get; set; }
}

As you can see, we've connected the elements from the JSON object to our .NET properties by using DataMember attributes. We've also implemented the IExtensibleDataObject interface, and told WCF to ignore any elements we haven't mapped explicitly and place them into what is effectively a bucket. Note that the media property is mapped to an instance of FlikrMedia, another type we have to declare to store the actual media imagery. All in all, our object model will look somewhat like:

CodeProject-ArbJson-Code

Reading the JSON

Next, we have to read the JSON data into our objects using the DataContractJsonSerializer. Before we do this though, we have to manually process the string to remove the callback wrapping around the real JSON data, since the jsonFlikrFeed() wrapping will otherwise cause parsing to fail. Next, we have to convert the string we've downloaded from the API into a buffer of bytes, place it into a memory stream, and then pass that through to the serializer.

static FlikrFeed ParseFeed(String inputContent)
{
    // Remove the jsonFlikrFeed() callback cladding.
    inputContent = inputContent.Trim();
    if (inputContent.StartsWith("jsonFlickrFeed("))
        inputContent = inputContent.Remove(0, "jsonFlickrFeed(".Length);
    if (inputContent.EndsWith(")"))
        inputContent = inputContent.Substring(0, inputContent.Length-1);

    // Create a serializer for our type
    DataContractJsonSerializer serializer = 
       new DataContractJsonSerializer(typeof(FlikrFeed));

    // Convert the text to a buffer of bytes
    using (MemoryStream stream = 
           new MemoryStream(Encoding.Unicode.GetBytes(inputContent)))
    {
        // Convert the stream buffer to an object with our serializer.
        return serializer.ReadObject(stream) as FlikrFeed;
    }
}

And, that is that! We've now got an instance of FlikrFeed we can browse the Items collection of, and also drill down to the media item preview image. You can apply these principles to any JSON feed you wish to interact with!

CodeProject-ArbJson-Result.png

Notes

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralFlickr Pin
TF_Productions
7:36 9 Feb '09  
GeneralRe: Flickr Pin
Steven James Gray
6:47 10 Feb '09  
GeneralGood article Pin
emiaj
5:08 5 Feb '09  


Last Updated 3 Feb 2009 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009