Recently I was working on an issue where a service would return null when called with some parameters and the consuming service would have an issue, because the response read from the HTTP response stream would be a string containing the 4 characters “null” and only had a check whether the string was null and if not was using a JSON converter to parse the JSON text which would result in an exception being thrown. The question we were discussing here is what should be the JSON representation of a null object.
What is JSON ?
JSON is described in a few standard documents:
- ECMA-404: The JSON Data Interchange Syntax
JSON text vs. JSON value
A JSON text is a sequence of tokens representing structured data transmitted as a string. A JSON value is be an object, array, number, or string, or one of the three literal names: false, null or true.
In RFC 4627, a JSON text was defined as serialized object or array. An JSON object value having to start and end with curly brackets and a JSON array value having to start and end with square brackets. This effectively meant that “null” was not a valid JSON text.
But even in RFC 4627, null was a valid JSON value.
Changes in RFC 7159
RFC 7159 was published in March 2014 and updates RFC 4627. The goal of this update was to remove inconsistencies with other specifications of JSON and highlight practices that can lead to interoperability problems. One of the changes in RFC 7159 is that a JSON text is not defined as being an object or an array anymore but rather as being a serialized value.
This means that with RFC 7159, “null” (as well as “true” and “false”) becomes a valid JSON text. So the JSON text serialized value of a null object is indeed “null”. Unfortunately, not all JSON parsers / deserializers support parsing the string “null”.
Parsing null with JSON.NET
When using JSON.Net (Newtonsoft.Json), there are two ways to deserialize a JSON text:
- JObject.parse: this returns a JObject which allows you to work with JSON results which structure might not be completely known.
- JsonConvert.DeserializeObject: this is always to deserialize the JSON text to an instance of a defined class.
JObject.parse unfortunately throws an exception when trying to parse “null” (JObject.Parse(“null”)):
Newtonsoft.Json.JsonReaderException: ‘Error reading JObject from JsonReader. Current JsonReader item is not an object: Null. Path ”, line 1, position 4.’
But if you do not have a class corresponding to the JSON text you’re deserializing, you can either use “object” as type when calling JsonConvert.DeserializeObject or use the overload without generics:
In both cases, you will get an instance of JObject back (just like the return value of JObject.parse).