当前位置: 首页 > 面试题库 >

json净前导零(禁用基播)

龙俭
2023-03-14
问题内容

Json.Net无法正确反序列化带有前导零的数字。

例如,{ "number":010 }识别为8(因为0108底等于810底)

如果看JsonTextReader.ParseNumber()你可以看到

long value2 = text2.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(text2, 16) : Convert.ToInt64(text2, 8);

如何禁用基本广播?也许可以更换JsonTextReader


问题答案:

由于JSON标准不允许使用前导零,因此Newtonsoft似乎决定实施JavaScript样式的八进制数字解析作为该标准的扩展,请参阅Json.NET
3.5 Release 7 –
Everest版本

。目前,这种行为已被硬编码为JsonTextReader.ParseReadNumber(ReadType readType, char firstChar, int initialPosition)不可强制严格遵守标准的选项(即在前导零处引发异常),如以下所述:

  • int解析无法正常工作#1057。
  • 反序列化带有前导零的数字#924。
  • 支持RFC7159解析#646的“严格模式”。

作为一种解决方法,您可以JavaScriptSerializer用来解析为中间动态对象,然后将其重新序列化为中间对象JToken,然后反序列化为JToken最终类:

var json = @"{ ""number"":010 }";

var root = JToken.FromObject(new JavaScriptSerializer().DeserializeObject(json)).ToObject<RootObject>();

if (root.Number != 10)
{
    throw new InvalidOperationException();
}

使用

class RootObject
{
    public int Number { get; set; }
}

您也可以重新序列化为中间的JSON字符串,但是JToken对于较大的对象,重新序列化为中间的应该更有效。

(如果您不需要Json.NET的全部功能,请切换到DataContractJsonSerializerJavaScriptSerializer,也可以选择这样做,因为两者都将以基数10静默地解析一个以零开头的整数。)

另一个选择是派生您自己的版本的JsonTextReader以及所有相关的实用程序,并修复JsonTextReader.ParseReadNumber()抛出JsonReaderExceptionwhen
nonBase10为true
的逻辑。不幸的是,JsonTextReader因为您还需要派生阅读器使用的所有Newtonsoft实用程序(有很多),并将它们更新为原始库中的任何重大更改,因此您自己进行分叉可能需要大量的日常维护。您也可以对要求严格的整数解析的增强请求#646投票或发表评论。

Newtonsoft为什么要以八进制语法实现数字解析?我的猜测是,他们添加了此功能来处理以JavaScript语法格式表示的整数数字:

整数

整数可以十进制(基数10),十六进制(基数16),八进制(基数8)和二进制(基数2)表示。

  • 十进制整数文字由 不带前导0(零) 的数字序列组成。
  • 整数文字前导0(零),或前导0o(或0O)表示它为八进制。八进制整数只能包含数字0-7。
  • 前导0x(或0X)表示十六进制。十六进制整数可以包含数字(0-9)以及字母af和AF。

  • 前导0b(或0B)表示二进制。二进制整数只能包含0和1的数字。



 类似资料:
  • 问题内容: 我有发票号码表。准则说数字应该有6个或更多的数字。首先尝试做: 但这效率不高,甚至还很漂亮。我尝试了LPAD功能,但是后来出现了问题,因为功能: 返回受影响的零行。还用谷歌搜索,他们说将引号设为零将解决问题,但是没有帮助吗?这是日常导入。 编辑:列NUMER为INT(19)并已包含如下数据: (目前,它已填充了3到7位不同长度的数据) 问题答案: 我认为您应该考虑阅读的指南适用于发票的

  • 问题内容: Javascript的parseInt函数似乎无法完全正常工作。 问题答案: 这是因为如果数字以“ 0”开头,则将其视为以8为基数(八进制)。 您可以通过将base作为第二个参数来强制使用base。 根据docs,第二个参数是可选的,但并不总是假定为10,如您从示例中看到的那样。

  • 问题内容: 因此,我正在从NOAA读取站代码csv文件,如下所示: 前两列包含气象站代码,有时它们的前导零。当熊猫在未指定dtype的情况下导入它们时,它们将变成整数。没什么大不了的,因为我可以遍历数据帧索引并用类似的东西替换它们,”%06d” % i因为它们始终是六位数字,但是您知道…这是懒惰的方式。 使用以下代码获取csv: 一切都很好,但是当我尝试使用此方法阅读时: 要么 我收到一个讨厌的错

  • 问题内容: 您可以使用该函数显示以零开头的整数吗? 输入示例: 所需的输出: 我知道和基于的格式(例如)都可以实现这一点。但是,我希望使用一种解决方案,以保持我的代码干净且一致(我还使用datetime属性格式化字符串),并扩展我对Format Specification Mini- Language的了解 。 问题答案: “{0:0>3}”.format(1) ‘001’ >>> “{0:0>3

  • 问题内容: 我想将Swift中的a 转换为前导零的a。例如,考虑以下代码: 当前的结果是: 但我希望它是: Swift标准库中是否有一种干净的方法可以做到这一点? 问题答案: 假设您希望字段长度为2,且前导零为零,则可以这样做: 输出: 这需要因此从技术上讲不是斯威夫特语言的一部分,而是由提供的功能框架。请注意这两个和包括因此没有必要再次导入它,如果你已导入或。 格式字符串可以指定多个项目的格式。

  • 问题内容: 我有下面的代码 和输出是 我期望输出如下。 当我打印直接int值时,为什么会给出?我期望Java自动将值从零开始转换为八进制。 和之间是什么关系? 问题答案: 前导0表示一个八进制数(以8为底)。 01111(八进制)是1 * 8 ^ 3 + 1 * 8 ^ 2 + 1 * 8 ^ 1 + 1 * 8 ^ 0 = 585(十进制) 将十进制数字1111转换为八进制字符串。八进制2127