• 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 却不行,如:

    //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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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 不支持dynamic

    Newtonsoft中的JObject/JArray 最终继承JToken,而JToken实现了IDynamicMetaObjectProvider接口,所以它设计支持dynamic操作;
    而JsonObject/JsonArray并没实现这个接口,不支持dynamic操作;
    在这里插入图片描述

    另外:网上有人讨论说 System.Text.Json 不支持DataTable
    经试验,序列化的时候确实报错了,原因是它不支持序列化Type对象,没错,就是不支持序列化typeof(Person),而 DataTable 里面就存了各种Type。。。
    DataTable并不是一个简单的类型,它是相当复杂的,一般我们将它转为list再序列化到前端,而不是直接序列化DataTable。。。
    事实上,Newtonsoft序列化DataTable后的字符串包含很多无用的东西,如下:
    在这里插入图片描述

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

    我选择了迁移,因为我不想依赖其他包,而且解决了一些不能够忍受的问题后,其他的感觉还ok。
    具体的代码参考:《DotNetCommon: JsonHelper》

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

    services.AddControllers().AddJsonOptions(options =>
    {
        JsonHelper.Configure(options.JsonSerializerOptions, 
             dateTimeFormatString: "yyyy-MM-dd HH:mm:ss", 
             lowerCamelCase: true);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    五、性能如何?

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

    在这里插入图片描述
    测试代码参考:

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

  • 相关阅读:
    3.4向量范数与矩阵范数&3.5线性方程组的迭代解法
    计算机组成原理(4)-----Cache的原理及相关知识点
    InVEST实践与进阶及在生态系统服务供需、固碳、城市热岛、论文写作
    VSCode实用远程主机功能
    慕思618静悄悄,暴利生意做不下去了?
    如何实现全网采集
    LC-3 机器语言 计算一个16位的字中有多少位是1
    JAVASE 第二十二天
    山西佳诺德:抖音选品技巧是什么
    leetcode 890. Find and Replace Pattern(查找和替换pattern)
  • 原文地址:https://blog.csdn.net/u010476739/article/details/133249245