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.

Saturday, October 20, 2012

.NET Rocks Road Trip

One of my favorite podcasts is the programming podcast .NET Rocks! Hosted by Carl Franklin and Richard Campell the show has had over 800 episodes since it’s debut in 2002. The show primarily focuses on development with .NET and other Microsoft technologies but also talks about general programming topics. Carl and Richard also host a podcast called The Tablet Show which focuses on mobile development for both Microsoft and non-Microsoft platforms.

Currently Carl and Richard are doing a road trip where they will be recording shows in 37 different cities all around the country. Today I had the pleasure of attending their event at the Microsoft office in Malvern PA. The road trip continues until December so I check out the list of future cities and see if there is one near you, I promise you will have a great time!

Here are some picture from today’s event.

DNR1
The 37’ RV they are traveling the country in.

DNR2
The Microsoft office in Malvern.

DNR3
Richard (center), Carl (right) and their guest for this show Glenn Block.

DNR4
Richard and Carl.

DNR5
Carl jamming for the crowd.

DNR6
Hanging out with the guys in the RV after the show and Carl providing a little entertainment.

Friday, October 5, 2012

Salesforce REST API Folders and Documents

In a recent post I described how to retrieve a file stored in Salesforce using the REST API. In that post I showed how to retrieve a document using its internal ID number which really isn’t to useful in practice, it would be better to retrieve it by name. In this post I will show how to look at folder and file information in Salesforce. All the queries in this post can be executed using the code I showed in the Salesforce REST API Query post.
Let’s start by looking at folders. You can query for a list of folders by using this SOQL statement:

SELECT ID,Name,DeveloperName FROM folder

This will return a JSON response something like this:

{
  "totalSize" : 1,
  "done" : true,
  "records" : [ {
    "attributes" : {
      "type" : "Folder",
      "url" : "/services/data/v24.0/sobjects/Folder/00lE0000000zg7MIAQ"
    },
    "Id" : "00lE0000000zg7MIAQ",
    "Name" : "Test Folder",
    "DeveloperName" : "Test_Folder"
  } ]
}

In the response you will see a record for each Folder in your Salesforce instance with fields for the ID, the folder name, and the DeveloperName which is a unique name without any spaces.

Now that we have the folder ID we can query for all the documents in that folder.

SELECT ID, Name, DeveloperName FROM document where Folderid='00lE0000000zg7MIAQ'

which will return a response like this:

{
  "totalSize" : 1,
  "done" : true,
  "records" : [ {
    "attributes" : {
      "type" : "Document",
      "url" : "/services/data/v24.0/sobjects/Document/015E00000019TzdIAE"
    },
    "Id" : "015E00000019TzdIAE",
    "Name" : "Test in Folder",
    "DeveloperName" : "Test_in_Folder"
  } ]
}


Just like the folder query this one returns an Id, Name and DeveloperName for each document in the folder. If you want you can also remove the where clause from that query and it will return a list of all documents no matter what folder they are in.

You might think that you could do something like this in one query using a join, but although SOQL does support joins, they don’t work with folders and documents, so you have to do the two separate queries.

Besides Id,Name and DeveloperName there are some other useful fields you can retrieve for a document.

LastModifiedById – Internal ID of the user that last modified the document record.
LastModifiedDate – Date that the document record was last modified.
CreatedById – Internal ID of the user that created the document record.
CreatedByDate – Date the document record was created.
AuthorID – Internal ID of the user who is currently selected as the author of the document.
Type – The file extension of the document.
ContentType – The MIME type of the document.
Keywords – The keywords field in the document record.
Description – The description field in the document record.
IsInternalUseOnly – The boolean Internal Use Only field in the document record.