由于前导零是不允许的JSON标准 http://www.json.org/,看来 Newtonsoft 决定实现 JavaScript 样式八进制数的解析作为标准的扩展,请参阅Json.NET 3.5 版本 7 – 有史以来最大的版本 http://james.newtonking.com/archive/2010/04/16/json-net-3-5-release-7-bson-binary-json-part-deux。此行为目前已硬编码到JsonTextReader.ParseReadNumber(ReadType readType, char firstChar, int initialPosition) https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/JsonTextReader.cs#L1942没有选项强制严格遵守标准(即在前导零上抛出异常),如下所示:
-
覆盖 Json 反序列化带有前导零的数字作为十进制而不是八进制值 https://stackoverflow.com/questions/29048110/override-json-deserializing-a-number-with-a-leading-zero-as-a-decimal-and-not-an.
-
Int 解析无法正常工作 #1057 https://github.com/JamesNK/Newtonsoft.Json/issues/1057.
-
反序列化带有前导零的数字 #924 https://github.com/JamesNK/Newtonsoft.Json/issues/924.
-
支持 RFC7159 解析的“严格模式”#646 https://github.com/JamesNK/Newtonsoft.Json/issues/646.
作为解决方法,您可以使用JavaScriptSerializer https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx解析为中间动态对象,然后将其重新序列化为中间对象JToken
,然后反序列化JToken
到你的最后一堂课:
var json = @"{ ""number"":010 }";
var root = JToken.FromObject(new JavaScriptSerializer().DeserializeObject(json)).ToObject<RootObject>();
if (root.Number != 10)
{
throw new InvalidOperationException();
}
Using
class RootObject
{
public int Number { get; set; }
}
您还可以重新序列化为中间 JSON 字符串,但重新序列化为中间JToken
对于较大的物体应该更有效。
(切换到DataContractJsonSerializer https://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx or JavaScriptSerializer
如果您不需要 Json.NET 的完整功能,也可以选择,因为两者都会默默地解析以 10 为基数的带前导零的整数。)
另一种选择是分叉你自己的版本JsonTextReader
以及所有相关的实用程序,并修复逻辑JsonTextReader.ParseReadNumber() https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/JsonTextReader.cs#L1942扔一个JsonReaderException
when nonBase10
是真的。不幸的是,分叉你自己的JsonTextReader
可能需要大量的持续维护,因为您还需要分叉读者使用的所有 Newtonsoft 实用程序(有很多)并将它们更新为原始库中的任何重大更改。您也可以投票或发表评论增强请求#646 https://github.com/JamesNK/Newtonsoft.Json/issues/646要求严格的整数解析。
Newtonsoft 为什么要实现八进制语法中的数字解析?我的猜测是他们添加了此功能来处理格式为整数文字的 JavaScript 语法 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Integers:
Integers
整数可以用十进制(基数为 10)、十六进制(基数为 16)、
八进制(基数为 8)和二进制(基数为 2)。