我们为什么推荐在Json中使用string表示Number属性值

简介: 在这篇简短的文章中,我将解释在使用JSON传输数据时,为什么浮点数或大十进制值应表示为字符串 。

long类型引发的诡异情况


长话短说,同事在利用swagger对接后端API时,诡异的发现swaggerUI中显示的json属性值并不是api返回的值。


[HttpGet]
public IActionResult QueryAsync()
{
   var testJson = new
   {
       Id =  123123126964992223,
       Profile = "Please attention on Id",
   };
   return new JsonResult(testJson);
}


该API在swagger输出:


{"Id": 123123126964992220,
 "Profile": "Please attention on Id"}


进一步从Chrome->[Network]->[Preview]、[Response payload]观察到该long属性值的

差异。


769f46fd36b8548275a0281cae0e61a2.jpg


直接给结论:部分long类型值(最大值2^63^-1)会超过Javascript的最大安全Number(2^53^-1), 浏览器/前端 使用JSON.parse(123123126964992223)将不再保证准确性。


617e9eba193166ed6b33d92a4a55a620.png


将JSON中的数字值作为字符串传输的是为了消除传输中的精度丢失或歧义性。


JSON规范中未给数值指定精度,JSON解析器会自由选择合适的数值精度。如果您的应用程序具有特定的精度要求,那么不同的JSON解析器可能不能正确表达精度。


另外部分long类型值(最大值263-1)会超过Javascript的最大安全Number(253 -1), 前端json反序列化时也会出现错误。


stackoverflow有个解释很赞:


b2372c0fab3c5d7d901913bd7556d609.jpg


覆写.NET Core序列化框架,将long转化为string


针对NewtonsoftJson编写BigIntJsonConvert


public class BigIntJsonConverter : JsonConverter<long>
    {
        public override long ReadJson(JsonReader reader, Type objectType, [AllowNull] long existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            var flag = long.TryParse(reader.Value.ToString(), out long num);
            return flag == true ? num : 0;
        }
        public override void WriteJson(JsonWriter writer, [AllowNull] long value, JsonSerializer serializer)
        {
            writer.WriteValue(value.ToString());
        }
    }
// 截取自Startup.cs ConfigureServices函数
  context.Services.AddMvc().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.Converters.Add(new BigIntJsonConverter());
});
相关文章
|
2天前
|
JSON 数据格式
使用 Gson 将 Map、List等转换为json string
使用 Gson 将 Map、List等转换为json string
13 0
|
2天前
|
SQL JSON Apache
Flink问题之嵌套 json 中string 数组的解析异常如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
229 1
|
2天前
|
JSON fastjson Java
(fastjson)java 如何将String(字符串)与JSON互转
(fastjson)java 如何将String(字符串)与JSON互转
88 1
|
2天前
|
JavaScript 前端开发
JavaScript基础语法:包括变量声明、数据类型(Number, String, Boolean, Null, Undefined, Symbol, Object)、运算符、流程控制语句(if...else, switch, for, while, do...while)等。
JavaScript基础语法:包括变量声明、数据类型(Number, String, Boolean, Null, Undefined, Symbol, Object)、运算符、流程控制语句(if...else, switch, for, while, do...while)等。
31 0
|
2天前
|
JavaScript 前端开发
js基础语法:包括变量声明、数据类型(Number, String, Boolean, Null, Undefined, Symbol, Object)、运算符、流程控制语句(if...else, switch, for, while, do...while)等。具体案例使用演示
js基础语法:包括变量声明、数据类型(Number, String, Boolean, Null, Undefined, Symbol, Object)、运算符、流程控制语句(if...else, switch, for, while, do...while)等。具体案例使用演示
36 1
|
6月前
|
存储 JavaScript 前端开发
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
39 0
|
6月前
|
存储 JavaScript 前端开发
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
【JS交互埋坑】事件函数自动将数字字符串String转为数值Number
91 0
|
8月前
|
存储 JSON NoSQL
【Redis从头学-4】Redis中的String数据类型实战应用场景之验证码、浏览量、点赞量、Json格式存储
【Redis从头学-4】Redis中的String数据类型实战应用场景之验证码、浏览量、点赞量、Json格式存储
169 0
|
9月前
|
JavaScript
ES6对String字符串、Array数组、Number数字、Object对象 类型做了哪些升级优化
ES6对String字符串、Array数组、Number数字、Object对象 类型做了哪些升级优化
|
10月前
|
存储 JavaScript 前端开发
JavaScript】基本数据类型与引用数据类型区别(及为什么String、Boolean、Number基本数据类型会有属性和方法?)
JavaScript】基本数据类型与引用数据类型区别(及为什么String、Boolean、Number基本数据类型会有属性和方法?)
72 0