Thursday, October 25, 2012

JSON.NET

Throughout the articles I have been writing on the Salesforce.com REST API I have been working with a lot of JSON data. One nice thing about the Salesforce REST API is that you have the choice to work with either JSON or XML data, but what if you are working with an API that only supports JSON? One option is to use the JavaScriptSerializer class that is available in the .NET Framework. You can read my Salesforce REST API Query Deserialization post for information on how to use this class. One of the downsides of this class is that it only supports serialization and deserialization of object models to and from JSON. Another more flexible option I have found for handling JSON is the JSON.NET library.
JSON.NET does support serialization between object and JSON, and claims to do it faster then JavaScriptSerializer, but it also provides some other ways of working with JSON including support for LINQ to JSON.
To get started with JSON.NET you will need to download the library from the Codeplex site. Inside the zip file you will find the source code along with pre-compiled binaries for Framework 2.0, 3.5 and 4.0 as well as versions for Silverlight, Windows Phone and WinRT. Copy the appropriate binaries to your project’s bin folder and then add a reference to it to your project. For the purposes of this demo I have also imported the Newtonsoft.Json.Linq namespace.
In the demo I am going to use this chunk of JSON which I have loaded into a string called jsonData.

{
  "totalSize" : 4,
  "done" : true,
  "records" : [ {
    "attributes" : {
      "type" : "Document",
      "url" : "/services/data/v24.0/sobjects/Document/015E0000000qhJeIAI"
    },
    "Id" : "015E0000000qhJeIAI",
    "Name" : "TestDocument",
    "FolderId" : "005E0000000V7EpIAK",
    "DeveloperName" : "TestDocument11"
  }, {
    "attributes" : {
      "type" : "Document",
      "url" : "/services/data/v24.0/sobjects/Document/015E0000000qV91IAE"
    },
    "Id" : "015E0000000qV91IAE",
    "Name" : "test",
    "FolderId" : "005E0000000V7EpIAK",
    "DeveloperName" : "test"
  }, {
    "attributes" : {
      "type" : "Document",
      "url" : "/services/data/v24.0/sobjects/Document/015E0000000qhIdIAI"
    },
    "Id" : "015E0000000qhIdIAI",
    "Name" : "test pdf",
    "FolderId" : "005E0000000V7EpIAK",
    "DeveloperName" : "test_pdf"
  }, {
    "attributes" : {
      "type" : "Document",
      "url" : "/services/data/v24.0/sobjects/Document/015E00000019TzdIAE"
    },
    "Id" : "015E00000019TzdIAE",
    "Name" : "Test in Folder",
    "FolderId" : "00lE0000000zg7MIAQ",
    "DeveloperName" : "Test_in_Folder"
  } ]
}

To work with the JSON the first thing we need to do is parse it with this line of code:

var obj = JObject.Parse(jsonData);

Once we have the JObject created it’s pretty easy to access the data in our JSON. For example what if we wanted to get the totalSize property. The code would look like this:

int totalSize = (int)obj["totalSize"];

Since totalSize is at the top level of the JSON we can use the property name as an index into obj and then cast the result to an integer. What if we now want to dig deeper into the JSON, for example to get the Id property of the first record.

string id = (string)obj["records"][0]["Id"];

In this line we first reference the records array in obj, then get the first record with the [0] index, and then finally the property name Id. We can keep stringing together numeric indexes and property names to get to any piece of data in the JSON. For example to get the url attribute in the first record we would use:

string url = (string)obj["records"][0]["attributes"]["url"];

So far we have only looked at accessing single value, but it’s also easy to iterate through an array.

var records = (JArray)obj["records"];

for (int i = 0; i < records.Count(); i++)
{
    Console.WriteLine(records[i]["Id"]);
}

To make the code a little easier to follow we first get the records array from obj which will return a JArray object. Now we can use a for loop to iterate through the elements of the array then use records[o][“Id”] to get the ID from each record.

No comments: