Json.NET 1.1 released

Thanks again to the people that have tried out Json.NET and have reported bugs or offered suggestions. This release addresses all the issues that you've reported and that I'm aware of. 1.1 also adds a few new features.

  • New feature - XmlNodeConverter class provides a means to easy convert between Xml and JSON text. SerializeXmlNode and DeserializeXmlNode helper methods have also been added.
  • New feature - Handles parsing JavaScript constructor calls (i.e. new Date(1234)).
  • New feature - Improved date serializing and deserializing.
  • Change - Rewritten JavaScript string escape method.
  • Bug fix - Lots of little fixes to JsonSerializer.

Converting between XML and JSON

The big new feature added in Json.NET 1.1 is a converter class for XML. By using XmlNodeConverter (or the newly added helper methods) it is now extremely simple to convert JSON to XML and vice versa in .NET.

XmlDocument doc = new XmlDocument();
doc.LoadXml(@"<?xml version=""1.0"" standalone=""no""?>
<root>
  <person id=""1"">
    <name>Alan</name>
    <url>http://www.google.com</url>
  </person>
  <person id=""2"">
    <name>Louis</name>
    <url>http://www.yahoo.com</url>
  </person>
</root>");
 
string jsonText = JavaScriptConvert.SerializeXmlNode(doc);
//{
//  "?xml": {
//    "@version": "1.0",
//    "@standalone": "no"
//  },
//  "root": {
//    "person": [
//      {
//        "@id": "1",
//        "name": "Alan",
//        "url": "http://www.google.com"
//      },
//      {
//        "@id": "2",
//        "name": "Louis",
//        "url": "http://www.yahoo.com"
//      }
//    ]
//  }
//}
 
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
 
Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);

Elements, attributes, text, comments, character data, processing instructions, namespaces and the XML declaration are all preserved when converting between the two. The only caveat is that it is possible to lose the order of differently named nodes at the same level when they are grouped together into an array.

A Brief Guide

  • Elements remain unchanged.
  • Attributes are prefixed with an @.
  • Single child text nodes are a value directly against an element, otherwise they are accessed via #text.
  • The XML declaration and processing instructions are prefixed with ?.
  • Charater data, comments, whitespace and significate whitespace nodes are accessed via #cdata-section, #comment, #whitespace and #significate-whitespace respectively.
  • Multiple nodes with the same name at the same level are grouped together into an array.
  • Empty elements are null.

Json.NET 1.1 can be downloaded here.

Json.NET 1.0.1 released

Changes in this version:

  • Bug Fix - JsonSerializer no longer errors when deserializing certain .NET objects.
  • Change - The JsonWriter QuoteChar property now defaults to double quotes and QuoteName is now true. This has been done to make the JSON output follow the json.org specification.
  • New Feature - JsonSerializer will attempt to use a classes TypeConverter to convert the JSON value to a members if the two do not match.

The new 1.0.1 version can been found on the download page.

Thank you to the people who have tried out Json.NET and given feedback.

Newton King - No Relation

When growing up from time to time when I gave my name to someone I was often asked if I had any any relation to the Newton King of Taranaki. Apart from knowing that someone of importance must have lived there, I never had any idea what they were talking about. After yet again being asked about the subject yesterday I bit the bullet and googled the name.

It turns out a man called Newton King (first name Newton, last name King) was born around 150 years ago and was quite a successful in business, running a company of the same name. Apparently prior to World War I, Newton King (the business) was the largest privately owned company in the Southern Hemisphere. Quite remarkable considering the small size of New Zealand.

This picture made me laugh:

And although the Newton King company went out of business during the 1987 stockmarket crash, there is still the Newton King Tanker Terminal at Port Taranaki today:

Thanks to the Puke Ariki museum for their great article on him.It feels good to put one of lifes puzzles to bed, kind of like learning why the sky is blue or why you should avoid virtual methods calls from a constructor. Now the next time someone inquires about my last name I can talk about the subject without looking like a total burk :)

Json.NET - Simplifying .NET <-> JavaScript communication

JSON (JavaScript Object Notation) is lightweight data interchange format. In recent times JSON has achieved widespread use due to the ease of which it can be parsed and then the data accessed from within JavaScript compared to alternatives like XML.

While many JavaScript libraries exist for converting JSON text to and from a JavaScript object, working with JSON in .NET has been much more problematic. Correctly escaping strings and building up objects when writing JSON text can be difficult and error prone, while parsing values back out of JSON text is harder still.

Json.NET

Json.NET is a JSON .NET API for simply and safely reading and writing valid JSON text. At the core of Json.NET, similar to the .NET XML APIs, are two classes: JsonReader and JsonWriter. Also like XML in .NET, Json.NET includes a JsonSerializer class.

Reading JSON

JsonReader is a fast, forward only, readonly cursor. Like XmlTextReader it works over the top of a TextReader and maximizes performance while minimizing memory use.

The following code is a brief example of how to read a JSON object.

string jsonText = "['JSON!',1,true,{property:'value'}]";
 
JsonReader reader = new JsonReader(new StringReader(jsonText));
 
Console.WriteLine("TokenType\t\tValueType\t\tValue");
 
while (reader.Read())
{
    Console.WriteLine(reader.TokenType + "\t\t" + WriteValue(reader.ValueType) + "\t\t" + WriteValue(reader.Value))
}

Resulting in...

TokenTypeValueTypeValue
StartArray null null
String System.String JSON!
Integer System.Int32 1
Boolean System.Boolean True
StartObject null null
PropertyName System.String property
String System.String value
EndObject null null
EndArray null null

Writing JSON

JsonWriter is also forward only, and writes JSON text to a TextWriter. It handles formatting numbers, escaping strings and validating that the object is valid.

The following code is a brief example of how to write a JSON object.

StringWriter sw = new StringWriter();
JsonWriter writer = new JsonWriter(sw);
 
writer.WriteStartArray();
writer.WriteValue("JSON!");
writer.WriteValue(1);
writer.WriteValue(true);
writer.WriteStartObject();
writer.WritePropertyName("property");
writer.WriteValue("value");
writer.WriteEndObject();
writer.WriteEndArray();
 
writer.Flush();
 
string jsonText = sw.GetStringBuilder().ToString();
 
Console.WriteLine(jsonText);
// ['JSON!',1,true,{property:'value'}]

Which prints out: ['JSON!',1,true,{property:'value'}].

Serializing and deserializing JSON and .NET objects

JsonSerializer, similar to XML serialization, provides a hassle free way to automatically convert .NET objects to and from JSON text.

The following code is a brief example of how to serialize and deserialize JSON and .NET objects.

string jsonText = "['JSON!',1,true,{property:'value'}]";
 
JsonSerializer serializer = new JsonSerializer();
 
JavaScriptArray jsArray = (JavaScriptArray) serializer.Deserialize(new JsonReader(new StringReader(jsonText)));
 
Console.WriteLine(jsArray[0]);
// JSON!
 
JavaScriptObject jsObject = (JavaScriptObject)jsArray[3];
 
Console.WriteLine(jsObject["property"]);
// value
 
StringWriter sw = new StringWriter();
 
using (JsonWriter jsonWriter = new JsonWriter(sw))
{
    serializer.Serialize(sw, jsArray);
}
 
Console.WriteLine(sw.GetStringBuilder().ToString());
// ['JSON!',1,true,{property:'value'}]

Json.NET - Json.NET Homepage