我们为什么推荐在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 Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
171 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
7月前
|
JavaScript 前端开发 索引
JavaScript有7个数据类型:Number, String, Boolean, Null, Undefined, Symbol(BES6)和BigInt(ES10)组成基本类型
【6月更文挑战第25天】JavaScript有7个数据类型:Number, String, Boolean, Null, Undefined, Symbol(BES6)和BigInt(ES10)组成基本类型,而Object包括Array、Function等是引用类型。Objects可以包含键值对,Array是特殊的Object。Functions也是对象。`null`和`undefined`被视为特殊的原始值。
61 1
|
7月前
|
存储 JSON 前端开发
为什么String跟JSON不是同个东西?
很多人会误解JSON仅仅是序列化后的String,但这样的表述并不完全准确。JSON本质上是以字符串(String)形式表示的数据交换格式,但它不仅仅是一个字符串,而是具有特定语法和结构的字符串。 很经常遇到的一个场景: 后端:我给你返回了一段JSON,你转化下再遍历吧。
TS定义布尔值,let flag:boolean = true,定义数字类型 let a1:number = 10,赋值 let str1:string = ‘‘,打印c~.log($(str1))
TS定义布尔值,let flag:boolean = true,定义数字类型 let a1:number = 10,赋值 let str1:string = ‘‘,打印c~.log($(str1))
TS,数据类型概述,常见的基本数据类型有number/string/boolean/undefined/null,字符串用““,let food: string = ‘糖葫芦‘,布尔类型
TS,数据类型概述,常见的基本数据类型有number/string/boolean/undefined/null,字符串用““,let food: string = ‘糖葫芦‘,布尔类型
|
8月前
|
JSON 数据格式
使用 Gson 将 Map、List等转换为json string
使用 Gson 将 Map、List等转换为json string
219 0
|
8月前
|
SQL JSON Apache
Flink问题之嵌套 json 中string 数组的解析异常如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
320 1
|
8月前
|
JSON fastjson Java
(fastjson)java 如何将String(字符串)与JSON互转
(fastjson)java 如何将String(字符串)与JSON互转
503 1
|
8月前
|
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)等。具体案例使用演示
90 1
|
8月前
|
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)等。
72 0