Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Consuming JSON data in .NET with WCF

4.74/5 (12 votes)
3 Feb 2009CPOL2 min read 105.4K   2.4K  
Code showing how to consume JSON data in your .NET applications using the new JSON data contract support in .NET 3.5 SP1.

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:

C#
[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.

C#
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

  • For more general information about JSON, there's a fairly good introduction to the basics of JSON at Google's GWT FAQ. This introduces the idea of wrapping JSON inside callback functions (as flikr has done in our example).
  • You need the .NET Framework 3.5 SP1 installed in order to run this code, and you can find the serializer in the System.ServiceModel.Web namespace.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)