c#:System.Text.Json 的使用三(从Newtonsoft迁移)

环境:

  • .net 6.0
  • vs2022

系列篇:
《c#:System.Text.Json 的使用一》
《c#:System.Text.Json 的使用二》
《c#:System.Text.Json 的使用三(从Newtonsoft迁移)》
参考:
《MSDN: 从 Newtonsoft.Json 迁移到 System.Text.Json》

一、为什么要从Newtonsoft迁移?

  • 不想再依赖三方包,虽然 Newtonsoft 已是"业界标准";
  • 想提升程序性能;

二、迁移中常见坑点

System.Text.Json 在提升性能的同时,也对反序列化时的json字符串进行了严格要求,而Newtonsoft则比较宽松,所以迁移后大概率会遇到json序列化问题,如下:

2.1 SystemTextJson 无法 "" => int? 无法转为null

严格来说,System.Text.Json 这么做并没有什么问题,但 Newtonsoft 允许啊,所以以前Api接口没问题,但换了 System.Text.Json 后就开始报错了。。。

为了兼容这种情况,我们需要自定义JsonConverter。。。(最后给出代码)

2.2 SystemTextJson 无法 123 => "123"

还是太严格导致的,为了兼容这种情况,我们需要自定义JsonConverter。。。(最后给出代码)

2.3 SystemTextJson 无法 true => "true"

还是太严格导致的,为了兼容这种情况,我们需要自定义JsonConverter。。。(最后给出代码)

2.4 SystemTextJson 无法 1 => true "true"=>true

还是太严格导致的,为了兼容这种情况,我们需要自定义JsonConverter。。。(最后给出代码)

2.5 SystemTextJson 无法 "NaN" => float.NaN

这个需要设置下就行了,但相对Newtonsoft 来说还是有点严格,但应该是没问题了。(最后给出代码)

为什么说设置后还还是有点严格呢,因为 Newtonsoft 还忽略大小写和从不带引号的string中反序列化,然后System.Text.Json 却不行,如:

csharp 复制代码
//Newtonsoft还兼容了大小写
d = Newtonsoft.Json.JsonConvert.DeserializeObject<Demo6>("{\"Float\":\"nan\"}");
d.Float.ShouldBe(float.NaN);
//Newtonsoft还兼容了不带引号的 NaN =>flaot.NaN
d = Newtonsoft.Json.JsonConvert.DeserializeObject<Demo6>("{\"Float\":NaN}");
d.Float.ShouldBe(float.NaN);

2.6 SystemTextJson 无法 "Close" => EnumState

这一点System.Text.Json 还是很差的,虽然可以设置将枚举转换为字符串,但读取的时候并不是自动的,也还需要设置,但在Api项目中,我们期望读取时允许 string => enum ,但返回时并不一定 enum => string,所以。。。(最后给出代码)

2.7 SystemTextJson 无法 "2023-09-21 01:02:03" => DateTime

默认 System.Text.Json 是遵从 ISO 8601-1:2019 标准,但还是太严格了,读取的时候就不能宽松些吗,毕竟Newtonsoft支持啊。。。(最后给出代码)

2.8 System.Text.Json 无法反序列化无引号的属性

其实这里还好,一般都会加引号的,如果没有加,就让对方改吧,毕竟这不符合json标准而且System.Text.Json 设计时就不允许。。。

三、System.Text.Json其他的功能缺陷

3.1 不支持 JsonPath 查询

当然,如果你没用过这么"高级"的功能,则可以忽略。

3.2 不支持 将DataTable 序列化为字符串

一般不会将 DataTable 序列化为字符串,因为DataTable本身包含了太多信息,即使是Newtonsoft,序列化后的结果也包含太多无用的东西,如下图所示:

一般我们会将 DataTable转为list再进行序列化和反序列化。

四、还要迁移到 System.Text.Json 嘛?

我选择了迁移,因为我不想依赖其他包,而且解决了一些不能够忍受的问题后,其他的感觉还ok。

具体的代码参考:《DotNetCommon: JsonHelper》

在应用到 asp.net core api中时,可以使用如下:

csharp 复制代码
services.AddControllers().AddJsonOptions(options =>
{
    JsonHelper.Configure(options.JsonSerializerOptions, 
         dateTimeFormatString: "yyyy-MM-dd HH:mm:ss", 
         lowerCamelCase: true);
});

五、性能如何?

System.Text.Json 性能确实强悍,随便一测,将近Newtonsoft的3倍,而我为了兼容Newtonsoft的功能,增加了一些设置和自定义转换器,就这样性能还是 Newtonsoft的2倍。

测试效果如下:

测试代码参考:

https://gitee.com/jackletter/DotNetCommon/blob/master/tests/SystemTextJsonPerformanceTest/Program.cs

相关推荐
202321336054 刘13 分钟前
Linux常用命令分类整理
linux·运维·数据库
Q741_14715 分钟前
海致星图招聘 数据库内核研发实习生 一轮笔试 总结复盘(2) 作答语言:C/C++ 哈夫曼编码 LRU
c语言·数据库·c++·算法·笔试·哈夫曼编码·哈夫曼树
黄金贼贼24 分钟前
2026最新java单元测试json校验器
java·单元测试·json
齐 飞24 分钟前
快速删除mysql表中所有数据-TRUNCATE TABLE
数据库·mysql
想摆烂的不会研究的研究生26 分钟前
每日八股——Redis(2)
数据库·redis·缓存
optimistic_chen29 分钟前
【Redis系列】主从复制
linux·数据库·redis·缓存·中间件·命令行·主从复制
一个天蝎座 白勺 程序猿33 分钟前
KingbaseES 处理 PL/SQL 运行时错误全解析:从异常捕获到异常处理的实践指南
数据库·sql·oracle·kingbasees
leo_23241 分钟前
表&表结构--SMP(软件制作平台)语言基础知识之三十三
数据库·开发工具·表结构·smp(软件制作平台)·应用系统
C***11501 小时前
Spring TransactionTemplate 深入解析与高级用法
java·数据库·spring
+VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue建筑材料管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计