json 网络前导零(禁用基本转换)

2024-05-27

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

例如{ "number":010 }被识别为 8(因为0108 基等于8以 10 为基数)

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

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

怎么可能禁用base-cast?也许可以替换JsonTextReader?


由于前导零是不允许的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)。

  • 十进制整数文字由数字序列组成没有前导 0(零).
  • 整数文字上前导 0(零),或前导 0o(或 0O)表示它是八进制的。八进制整数只能包含数字 0-7。
  • 前导 0x(或 0X)表示十六进制。十六进制整数可以包含数字 (0-9) 以及字母 a-f 和 A​​-F。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

json 网络前导零(禁用基本转换) 的相关文章

  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • jQuery:处理 getJSON() 中的错误?

    使用 jQuery 时如何处理 500 错误getJSON http api jquery com jQuery getJSON 有几个关于错误处理的问题getJSON and https stackoverflow com questio
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK

随机推荐