Working with JSON and C#–for Lazy Programmers

It just so happens that only a day ago I embarked on using Nokia’s HERE Places API in a new app. Then this morning saw a tweet by Lance McCarthy:

And, after checking out http://json2csharp.com/, realized I was much better off using its generated classes than what I had been doing, which was just grabbing what I needed into a relatively barebones class using a dynamic object.

Dynamics are great. But in this case, it’s so much better using the generated class. If it wasn’t for the json2csharp converter I wouldn’t bother because I don’t need all that is spewed out by the Places API…and it is verbose. But just getting Intellisense alone makes it pure gold. (Shout out to Lance and to Jonathan Keith, the creator/maintainer of the site).

Let’s look at some code comparisons. Creating a new object using the class is a bit more verbose, but certainly no more complicated:

var placeInfo = await Task.Factory.StartNew(() => JsonConvert.DeserializeObject<HerePlaceInfo>(responseStr), cancellationToken);

vs:

dynamic dynObject = await Task.Factory.StartNew(() => JObject.Parse(responseStr), cancellationToken);

But from then on it gets much nicer working with it:

var oTitle = placeInfo.related.publicTransport.href;

vs:

var dTitle = dynObject.related["public-transport"].href.Value;

The former provides Intellisense all the way (very useful for delving into nested JSON schemas) as well as a less complicated, shorter syntax.

You may have noticed in this particular example the “public-transport” key has a hyphen. That is something I wish the authors of the HERE Places API hadn’t done. The Json2Csharp converter flagged this since it couldn’t create a proper camelCase name. Even if it had, that wouldn’t do any good because it wouldn’t automatically match incoming JSON, leaving us with a null value.

To get around this, you can give the item a legal name and decorate it:

[JsonProperty(PropertyName = "public-transport")]
public PublicTransport publicTransport { get; set; }

You don’t have to do anything to the class that it references, e.g:

public class PublicTransport
{
public string title { get; set; }
public string href { get; set; }
public string type { get; set; }
}

Here’s another example, digging into the location data to mine the latitude and longitude:

var locationY = placeInfo.location.position[0];
var locationX = placeInfo.location.position[1];

var locPoint = new Point(locationX2, locationY2);

vs.

var locationY = (double) dynObject.location.position[0];
var locationX = (double) dynObject.location.position[1];

var locPoint = new Point(locationX, locationY);

And if you still aren’t convinced, consider that with a dynamic you can’t use LINQ (at least not easily…and I’ll leave that to others):

var categories2 = placeInfo.categories.Select(category => category.title).ToList();

vs:

var categories = new List<string>();

var catArray = dynObject.categories;

foreach (var category in catArray)
{
categories.Add(category.title.Value);
}

If the JSON2Csharp class seems verbose, keep in mind you can comment out or delete the parts you won’t need. That won’t prevent JSON.NET from populating the object instance.