.net 关于在program中使用AddNewtonsoftJson之后,继承于System.Text.Json.Serialization的自定义转换器JsonConverter不生效的问题

发布时间 2023-10-11 16:34:37作者: 六月Talk

  首先,先说遇见的问题与代码示例,在.net代码中注册了如下代码

 .AddNewtonsoftJson(option =>
                {
                    //使用本地时区
                    option.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
                    //日期格式
                    option.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss.fff";
                    //忽略循环引用
                    option.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                })

  该代码使用了第三方库Newtonsoft.Json,该库是比较好用的一个json序列化库。这里也是为了去对日期格式做一个全局序列化的操作。在使用了AddNewtonsoftJson之后出现了一个问题,自定义的继承了System.Text.Json.Serialization的转换器就不生效了,这里博主是按照最高优先级属性注册的,这里困扰了博主,于是开始查资料(可能是因为博主不是大佬,这种问题也能困扰,最后得出结论是使用了第三方,官方的就没用了,那么这里博主参照官方的解释,还有了新的疑惑)。

 

  下面是博主查询官方资料得到的解释,也是查了很久,虽然资料比较少,但是官方写在了一些奇怪的地方。

1.使用的了AddNewtonsoftJson,AddNewtonsoftJson 替换了基于 System.Text.Json 的默认输入和输出格式化程序,该格式化程序用于设置所有JSON 内容的格式。

出处:ASP.NET Core Web API 中的 JSON 修补程序 | Microsoft Learn

这里,官方是放在了菜单:处理JSON Patch请求的文章里面,也是找了半天才找到该描述。

 

 

2.基于第一点,NewtonsoftJson相当于代替了System.Text.Json成为了内置转换器,那么我在使用时应该遵守下面这点:仅当未注册适用自定义转换器时,才会选择内置转换器。

出处:如何编写用于 JSON 序列化的自定义转换器 - .NET | Microsoft Learn

这里官方在转换器的注册优先级有说明,会使用自定义转换器。

 3.基于第二点,我在代码中使用了继承System.Text.Json的自定义转换器,并且使用了优先级最高的属性注册,那么应该是自定义转换器优先级最高,应该生效。但是事实是并没用生效。

出处:从 Newtonsoft.Json 迁移到 System.Text.Json - .NET | Microsoft Learn

综上:目前的理解为,当没有使用AddNewtonsoftJson 时,优先级按照官方给出的,属性注册最高,是生效的。当使用了AddNewtonsoftJson 时,官方的System.Text.Json是被NewtonsoftJson默认设置了,System.Text.Json是不生效的。产生的疑惑:按照官方给出的优先级与上面第二点的说明,如果我自定义了转换器,并且按照优先级最高的属性注册,无论是否是使用了AddNewtonsoftJson,其实都应该生效的。我们应该是要遵循优先级原则的,否则的话,一旦我使用了AddNewtonsoftJson,那我就并不能使用System.Text.Json的自定义转换器了?

  这里,博主也和朋友讨论过,按照目前的测试与资料来看,当使用了第三方json序列化库,官方的text.json库就没用了,会被强制给使用第三方库,就算自定义转换器也是没有用的,自始至终会使用Newtonsoft.Json库的转换器,那这里其实是一个强制的点了。

  最后,博主其实是工作中需要使用到自定义转换器,最后还是注释掉了AddNewtonsoftJson的部分,使用了官方的json库,这样自定义转换器更灵活,虽然可能需要在更多的属性上面去加这样一个转换器,但是对于使用来说更加灵活,也更加的方便。

JSON Patch