.NET Core 3.0 System.Text.Json 和 Newtonsoft.Json 行为不一致问题及解决办法

行为不一致

.NET Core 3.0 新出了个内置的 JSON 库, 全名叫做尼古拉斯 System.Text.Json - 性能更高占用内存更少这都不是事...

对我来说, 很多或大或小的项目能少个第三方依赖项, 还能规避多个依赖项的依赖 Newtonsoft.Json 版本不一致的问题, 是件极美的事情.

但是, 结果总不是不如预期那么简单和美好, 简单测试了下, 有一些跟 Newtonsoft.Json 行为不一致的地方, 代码如下:

using Microsoft.VisualStudio.TestTools.UnitTesting;namespace UnitTestProject3
{[TestClass]public class TestJsonDiff{[TestMethod][Description(description: "测试数字序列化")]public void TestNumber(){object jsonObject = new { number = 123.456 };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "测试数字序列化失败");}[TestMethod][Description(description: "测试英文序列化")]public void TestEnglish(){object jsonObject = new { english = "bla bla" };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "测试英文序列化失败");}[TestMethod][Description(description: "测试中文序列化")]public void TestChinese(){object jsonObject = new { chinese = "灰长标准的布咚发" };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "测试中文序列化失败");}[TestMethod][Description(description: "测试英文符号")]public void TestEnglishSymbol(){object jsonObject = new { symbol = @"~`!@#$%^&*()_-+={}[]:;'<>,.?/ " };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "测试英文符号失败");}[TestMethod][Description(description: "测试中文符号")]public void TestChineseSymbol(){object jsonObject = new { chinese_symbol = @"~·@#¥%……&*()—-+={}【】;:“”‘’《》,。?、" };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "测试中文符号失败");}}
}

先来看看总体的测试结果:

这是 VS 显示的结果

640?wx_fmt=png

这是执行 dotnet test 命令行显示的结果

640?wx_fmt=png

这个时候需要配个图

640?wx_fmt=png

那么问题来了, 国庆去哪玩比较好呢, 我是谁? 这是哪? 发生了什么?

解决办法

解决中文会被 Unicode 编码的问题

这个问题是在博客园里找到的一种答案: .NET Core 3.0 中使用 System.Text.Json 序列化中文时的编码问题

[TestMethod]
[Description(description: "测试中文序列化")]
public void TestChinese()
{object jsonObject = new { chinese = "灰长标准的布咚发" };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject,options: new System.Text.Json.JsonSerializerOptions{Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(allowedRanges: UnicodeRanges.All)});Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "测试中文序列化失败");
}

关键在于序列化配置加了一句

new System.Text.Json.JsonSerializerOptions
{Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(allowedRanges: UnicodeRanges.All)
}

但是一些符号被转义的问题还是不管用, 寻思了一上午暂时没找到答案...

至于什么时候修复此类问题,

640?wx_fmt=jpeg

我去源码 corefx 溜个一圈, 暂时的发现是归到了 .NET Core 3.1 和 5.0 的开发时间线里...后面回来发现这不应该啊

但是...难道就这样了?

怀着受伤的核桃心, 中午又吃了3只大闸蟹...

诡异的是新建 ASP.NET Core API (.NET Core 3.0) 输出的 JSON 中文和转义字符都是正常, 如图:

640?wx_fmt=png

说明一定是我们打开的方式不对...回娘家找源码, 寻寻匿匿最后发现这么一句

// If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters.
jsonSerializerOptions = jsonSerializerOptions.Copy(JavaScriptEncoder.UnsafeRelaxedJsonEscaping);

less strict ? 那对照的意思是 Newtonsoft.Json 一直使用的就是非严格模式咯, 而我们习惯使用的也是这种模式.

那么改下, 还报错的单元测试都加上配置 JavaScriptEncoder.UnsafeRelaxedJsonEscaping, 果然测试结果顺眼多了. 连上面的 UnicodeRanges.All 都不需要配置了.

string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject,options: new System.Text.Json.JsonSerializerOptions{Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping});

640?wx_fmt=png

又整明白一个问题, 开森...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313597.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java9 新特性

在介绍 java9 之前&#xff0c;我们先来看看java成立到现在的所有版本。 1990年初&#xff0c;最初被命名为Oak&#xff1b;1995年5月23日&#xff0c;Java语言诞生&#xff1b;1996年1月&#xff0c;第一个JDK-JDK1.0诞生&#xff1b;1996年4月&#xff0c;10个最主要的操作系…

深入探究Kubernetes - 初识容器

♥2019年8月28星期三第47篇原创引言最近Kubernetes比较火&#xff0c;新技术快速火起来&#xff0c;一定有它强大的优势&#xff0c;Hr反馈&#xff0c;招聘时会Kubernetes的很少&#xff0c;风口上的Kubernetes一起学学&#xff1f;扫盲贴&#xff0c;参考《Kubernetes进阶实践…

Java11 新特性

Java 11新特性的详细解释。JDK 11已经于 2018年9月25日正式发布&#xff0c;那么Java 11主要包含哪些新特性呢&#xff1f; JDK 11是Java SE 11平台版本11的开源参考实现&#xff0c;由JSR 384在Java Community Process中指定。 阿里巴巴是中国唯一的JCP委员会成员公司&#x…

福爆 | 博客升级 .NET Core 3.0 又踩一坑

点击上方蓝字关注“汪宇杰博客”导语昨天刚发了一篇《生产大爆炸发生问题的是已经被删除的博客文章&#xff0c;正常情况下&#xff0c;这些不存在的文章会直接显示自定义的404页面&#xff0c;但实际上产生了500异常。日志如下&#xff1a;2019-09-26 00:11:50.8405|RD00155DB…

Sping5——响应式编程

1、响应式编程基础 1.1、什么是响应式编程&#xff1f; 响应式编程是一种面向数据流和变化传播的编程范式。 使用它可以在编程语言中很方便地表达静态或动态的数据流&#xff0c;而相关的计算模型会自动将变化的值通过数据流进行传播。我们可以使用声明的方式构建应用程序的能…

.NET Core使用NPOI导出复杂Word详解

最近使用NPOI做了个导出Word文档的功能&#xff0c;关于使用.NET Core 导出Word文档的方式有很多。最终我为什么选择了NPOI来实现了这个功能&#xff0c;首先是NPOI是一个开源&#xff0c;免费且容易上手的第三方框架&#xff08;并且现在已支持.NET Core&#xff0c;GitHub源码…

Spring Boot 2.0新特性

Spring Boot依赖于Spring&#xff0c;而Spring Cloud又依赖于Spring Boot&#xff0c;因此Spring Boot2.0的发布正式整合了Spring5.0的很多特性&#xff0c;同样后面Spring Cloud最新版本的发布也需要整合最新的Spring Boot2.0内容。 一、新版本特性 1.1&#xff0c;基于 Jav…

为了不让代码“作恶”,能否将道德条款纳入开源许可证?

随着特朗普政府反移民政策的执行&#xff0c;成千上万的移民儿童与父母分离&#xff0c;美国移民和海关执法局&#xff08;ICE&#xff09;也因此成为众矢之的。所以&#xff0c;当开源开发者 Seth Vargo 发现前东家 —— Chef 公司最近与 ICE 签订了合同后&#xff0c;进行删库…

dump获取与分析

一、dump基本概念 在故障定位(尤其是out of memory)和性能分析的时候&#xff0c;经常会用到一些文件来帮助我们排除代码问题。这些文件记录了JVM运行期间的内存占用、线程执行等情况&#xff0c;这就是我们常说的dump文件。常用的有heap dump和thread dump&#xff08;也叫ja…

dump分析死锁

1、制造死锁场景 一段死锁程序 public class DeadLock {public static Object lockA new Object();public static Object lockB new Object();public static void main(String[] args) {new ThreadA().start();new ThreadB().start();} }class ThreadA extends Thread {Ove…

用 C# 来守护 Python 进程

背景目前我主要负责的一个项目是一个 C/S 架构的客户端开发&#xff0c;前端主要是通过 WPF 相关技术来实现&#xff0c;后端是通过 Python 来实现&#xff0c;前后端的数据通信则是通过 MQ 的方式来进行处理。由于 Python 进程是需要依赖客户端进程来运行&#xff0c;为了保证…

针对媒体不实报道误导大众--抹黑C#工资垫底

近注意到一些媒体故意抹黑C# 工资垫底,参见 https://www.toutiao.com/i6741889572931633668/:通过搜索引擎搜索《编程语言薪酬排行&#xff1a;Python薪资最高&#xff0c;Java第二&#xff0c;C# 垫底》&#xff1a;早在2018年就出现这样的标题内容&#xff0c;还是CSDN公众号…

程序员你写的代码,被人挖出了黑产

事件经过看了微博上发表转发1000 、点赞1000次的吐槽陕西省的普通话成绩查询网站代码的微博&#xff0c;后来知乎上又有20万的阅读量这个话题的提问。最终结案这并不是真的陕西省普通话成绩查询网的网址&#xff0c;只不过是和官方查询一样的界面&#xff0c;李鬼”网站&#x…

Java垃圾回收日志解析

1.开启垃圾回收日志 在运行一个java程序时可以在命令行中加入相应的JVM垃圾回收参数&#xff0c;获取程序运行时详细的垃圾回收日志信息。以下是一些大概的参数&#xff1a; -XX:PrintGC与-verbose:gc 这两个命令效果都是一样&#xff0c;打印最基本的回收信息 -XX:PrintGCDe…

感谢有你们,架构师修行之路!

感谢有你们转眼马上就十月一了&#xff0c;听说今年的阵势非常强大&#xff0c;菜菜虽然身在北京&#xff0c;但是可能也目睹不了这个激动时刻了。自从2018年年底决定开始写公众号以来&#xff0c;几乎每个周末都在构思文章&#xff0c;撰写文章。关注公众号的老粉丝应该知道&a…

自定义构建基于.net core 的基础镜像

先说一个问题首先记录一个问题&#xff0c;今天在用 Jenkins 构建项目的时候突然出现包源的错误&#xff1a;/usr/share/dotnet/sdk/2.2.104/NuGet.targets(114,5): error : Unable to load the service index for source https: /usr/share/dotnet/sdk/2.2.104/NuGet.targets(…

操作系统——缓冲区溢出

一、缓冲区溢出介绍 1988年&#xff0c;世界上第一个缓冲区溢出攻击–Morris蠕虫在互联网上泛滥&#xff0c;短短一夜的时间全世界6000多台网络服务器瘫痪或半瘫痪&#xff0c;不计其数的数据和资料被毁。造成一场损失近亿美元的空前大劫难&#xff01; 那么&#xff0c;缓冲…

从壹开始学习 NetCore 新篇章 ║ Blog.Core 开发社之招募计划书

宫哈喽大家好&#xff0c;国庆马上就要来了&#xff0c;在新的第四季度来临之际&#xff0c;祝大家年末能顺顺利利&#xff0c;解决所有的难题。大家可能从我的标题里也能看的出来&#xff0c;老张又要耍花样&#xff0c;搞事情了&#xff0c;近来随着 netcore 3.0 的正式推出&…

操作系统——内存管理——分段和分页

一、 物理地址和逻辑地址 物理地址&#xff1a;加载到内存地址寄存器中的地址&#xff0c;内存单元的真正地址。在前端总线上传输的内存地址都是物理内存地址&#xff0c;编号从0开始一直到可用物理内存的最高端。这些数字被北桥(Nortbridge chip)映射到实际的内存条上。物理地…

Kubernetes攻略之新手上路

在公有云、私有云和混合云的环境中&#xff0c;Kubernetes已经成为规模化部署容器应用的事实标准。最大的公有云平台AWS、谷歌云、Azure、IBM云和Oracle云目前都提供Kubernetes的管理服务&#xff08;Managed Services&#xff09;。各大互联网公司也开始将服务部署到Kubernete…