Json.NET does not currently implement strict parsing of JSON property names.
Internally JToken.Parse()
constructs a JsonTextReader
to parse a JSON string, and it appears the ability of JsonTextReader
to parse unquoted property names cannot currently be disabled.
When iterating through a JSON file via JsonTextReader.Read()
, the method JsonTextReader.ParseProperty()
is used to parse property names:
Newtonsoft.Json.JsonTextReader.ParseUnquotedProperty()
Newtonsoft.Json.JsonTextReader.ParseProperty()
Newtonsoft.Json.JsonTextReader.ParseObject()
Newtonsoft.Json.JsonTextReader.Read()
Newtonsoft.Json.Linq.JContainer.ReadTokenFrom()
And, as seen from the current reference source, this method automatically handles properties that are double-quoted, single-quoted and unquoted:
private bool ParseProperty()
{
char firstChar = _chars[_charPos];
char quoteChar;
if (firstChar == '"' || firstChar == '\'')
{
_charPos++;
quoteChar = firstChar;
ShiftBufferIfNeeded();
ReadStringIntoBuffer(quoteChar);
}
else if (ValidIdentifierChar(firstChar))
{
quoteChar = '\0';
ShiftBufferIfNeeded();
ParseUnquotedProperty();
}
else
{
throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}
// REMAINDER OMITTED
As you can see there is no option to configure the reader to throw an exception for non-double-quoted properties.
As a workaround, the current Json.NET license allows for copying and modification. Thus you should be able to create your own public class StricterJsonTextReader : JsonReader
copied from JsonTextReader
, and modify ParseProperty()
as follows:
private bool ParseProperty()
{
char firstChar = _chars[_charPos];
char quoteChar;
if (firstChar == '"')
{
_charPos++;
quoteChar = firstChar;
ShiftBufferIfNeeded();
ReadStringIntoBuffer(quoteChar);
}
else
{
// JsonReaderException.Create() is an internal static method,
// so you will need to replace this with some extension method
throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}
However, this may not be an entirely easy job, as JsonTextReader
makes extensive use of utilities from the Src/Newtonsoft.Json/Utilities
directory. You should budget a couple of days for making a minimal copy of the necessary utilities.
Alternatively, you could fork your own version of Json.NET, build it yourself, and use it instead of the official version. Either way, be sure to fork the source from the version you want to use:

As an alternative to creating your own parser, you could preprocess your JSON with JsonReaderWriterFactory.CreateJsonReader()
to ensure strict compliance with the JSON standard:
public static class JsonExtensions
{
public static JToken StrictParse(string json)
{
try
{
// Throw an exception if the json string is not in strict compliance with the JSON standard
// by tokenizing it with the JSON reader used by DataContractJsonSerializer:
using (var stream = GenerateStreamFromString(json))
using (var reader = System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(stream, System.Xml.XmlDictionaryReaderQuotas.Max))
{
while (reader.Read())
{
}
}
}
catch (Exception ex)
{
// Wrap the XmlException in a JsonReaderException
throw new JsonReaderException("Invalid JSON", ex);
}
// Then actually parse with Json.NET
return JToken.Parse(json);
}
static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value ?? ""));
}
}
(You will need to add a reference to the appropriate .Net assembly for your framework.)
The performance will be worse since you will effectively be parsing your JSON twice, but the implementation effort is trivial.
Oddly enough, I was unable to use JavaScriptSerializer
to check for strict JSON compliance because it also accepts unquoted property names!
// The following does not throw an exception:
new System.Web.Script.Serialization.JavaScriptSerializer().DeserializeObject("{foo : 'bar'}")
Related links: