解决System.Text.Json中文编码问题:配置UnsafeRelaxedJsonEscaping

System.Text.JsonJSON序列化Unicode转义
于 2026-08-04 06:59:27 修改
·本内容遵循CC 4.0 BY-SA版权协议

1. 项目概述:当JSON输出不再“友好”

在.NET Core 3.0及更高版本的开发中,System.Text.Json作为微软官方力推的高性能JSON序列化库,已经逐渐成为处理JSON数据的首选。它速度快、内存占用低,对于构建高性能API和微服务来说,是一个利器。然而,很多开发者,包括我自己在内,在从经典的Newtonsoft.Json即Json.NET)迁移过来,或者初次使用时,都踩过一个不大不小的坑:当你满怀期待地将一个包含中文或特殊符号(比如引号、斜杠、Emoji)的对象序列化成JSON字符串时,得到的输出却是一串令人困惑的Unicode转义序列,例如\u4e2d\u6587(代表“中文”)或者\u0022(代表双引号)。在控制台输出或者前端接收时,这看起来就是一堆乱码,严重影响了数据的可读性和调试体验。

这个问题看似简单,却直接关系到开发效率和数据的直观性。想象一下,你正在调试一个返回用户信息的API,日志里看到的用户名全是\u5f20\u4e09,而不是清晰的“张三”,这无疑增加了排查问题的难度。更关键的是,某些下游系统或前端框架可能对这类编码字符串的处理并不一致,从而引发更深层次的兼容性问题。因此,理解System.Text.Json的编码行为,并掌握如何控制它,是每一位.NET开发者在使用这个库时必须掌握的技能。本文将深入拆解其背后的原理,并提供从全局配置到局部控制的完整解决方案,让你输出的JSON既高性能,又“人见人爱”。

2. 核心原理:为什么System.Text.Json要“编码”?

要解决问题,首先要理解问题是如何产生的。System.Text.Json默认对非ASCII字符(包括中文)和某些特殊字符进行转义,这并非一个Bug,而是一个经过深思熟虑的默认安全设计。

2.1 编码与转义的本质区别

这里需要先厘清一个概念:我们常说的“乱码”和“编码”在这个语境下,通常指的是“字符转义”。真正的编码(如UTF-8、GBK)发生在字节层面,而System.Text.Json输出的是字符串,它涉及的是字符串内部的字符表示方式。

默认情况下,System.Text.JsonJsonSerializer使用了一个名为JavaScriptEncoder.UnsafeRelaxedJsonEscaping的编码器(更准确地说,默认是比UnsafeRelaxedJsonEscaping更严格的规则)。这个编码器的设计遵循了JSON规范(RFC 8259)和防范特定安全风险的原则,主要体现在两点:

  1. 非ASCII字符转义:将所有不在基本拉丁语(Basic Latin)区块(即码点大于\u007F)的字符转换为\uXXXX的Unicode转义序列。例如,汉字“中”的Unicode码点是U+4E2D,就会被转义为\u4e2d。这样做可以确保生成的JSON文本完全由ASCII字符构成,具有极佳的兼容性。无论接收方的系统使用何种字符编码(即使是古老的只支持ASCII的环境),这份JSON文件在语法上都是绝对安全的,不会因为编码问题导致解析失败。

  2. HTML敏感字符转义:默认编码器会转义一些在HTML和XML上下文中具有特殊意义的字符,例如<>&等。这是为了防止JSON被意外嵌入HTML时可能引发的跨站脚本攻击风险。例如,字符串“<script>”会被转义为“\u003Cscript\u003E”

2.2 与Newtonsoft.Json的默认行为对比

这也是许多开发者感到困惑的根源。Newtonsoft.Json的默认行为要“宽松”得多,它通常直接输出原始字符(如中文),除非你显式配置了转义。这种差异导致了迁移时的“水土不服”。System.Text.Json将“安全”和“兼容性”放在了更高优先级,而Newtonsoft.Json则更注重“可读性”和“开发者习惯”。

注意System.Text.Json的严格默认行为,在构建需要面对不可信输入或多种异构环境的高安全性、高可靠性服务时,是一个优势。但在大多数内部系统、前后端分离且字符集统一(如全栈UTF-8)的Web API场景中,这种转义就显得多余且不友好了。

3. 解决方案全景:从全局到局部的控制

明白了原因,解决方案就清晰了:我们需要告诉System.Text.Json,在序列化时使用一个更“宽松”的编码器,允许非ASCII字符和更多符号以原样输出。微软提供了几个不同安全等级的编码器供我们选择。

3.1 可用的编码器选项

System.Text.Json主要通过JsonSerializerOptions类来配置序列化行为,其中Encoder属性是关键。我们可以使用的编码器来自System.Text.Encodings.Web命名空间下的JavaScriptEncoder类:

编码器 安全性 转义行为 适用场景
JavaScriptEncoder.Default 转义所有非ASCII字符及HTML敏感字符(<, >, &, ', "等)。这是JsonSerializer默认编码器。 最高安全需求,输出环境未知或不可控。
JavaScriptEncoder.UnsafeRelaxedJsonEscaping 允许非ASCII字符(如中文)原样输出。但仍会转义少数几个在JSON字符串和HTML中都必须转义的字符,如引号(")和反斜杠(\)。这是最常用的解决中文乱码问题的选项。 绝大多数Web API场景,前后端均使用UTF-8,且信任数据源。
JavaScriptEncoder.Create 可定制
最低 0.47元/天 开通会员,解锁全文
left
成为会员后, 你将解锁
right
benefits 下载资源随意下
benefits 优质VIP博文免费学
benefits 优质文库回答免费看
benefits 付费资源9折优惠
System.Text.Json vs Newtonsoft2024年C# JSON库性能对比与选型指南
本文基于.NET 8环境下的基准测试与实战经验,对比System.Text.Json与Newtonsoft.Json在序列化/反序列化性能、UTF-8原生支持、GC压力、JSON DOM、安全性、多态支持、JSON Path、配置灵活性及迁移成本等方面的差异;明确高性能新项目首选System.Text.Json,而遗留系统或需循环引用、TypeNameHandling等高级特性的场景仍适用Newtonsoft.Json
1086
从 Newtonsoft.Json 迁移到 System.Text.Json
本文详细比较了.NETCore中的System.Text.Json和Newtonsoft.Json在序列化、反序列化、特性处理、性能和兼容性等方面的差异,为从Newtonsoft.Json迁移到System.Text.Json提供实用指导。
ZL4120505
1834
C#序列化从 Newtonsoft.Json 迁移到 System.Text.Json
本文介绍了在.NET生态中,从Newtonsoft.Json迁移到System.Text.Json的相关内容。阐述了选择System.Text.Json的原因,包括性能、内置支持与安全性、现代化特性等优势。详细说明了迁移步骤、高级场景处理、性能优化技巧,还给出常见问题解决方案,助力开发者完成迁移。
阿蒙Armon
1164
Asp .Net Core 系列Asp .Net Core 配置 System.Text.Json
本文介绍了System.Text.Json命名空间的功能,包括序列化和反序列化,强调其高性能和低内存分配,支持UTF - 8编码。阐述了在Asp.Net Core中配置System.Text.Json的方法,对比了与Newtonsoft.Json的差异,还提及无实体类型操作Json、自定义转换器、处理Dynamic类型等内容,并封装了JsonHelper帮助类。
Code技术分享
2080
C#中System.Text.Json:从入门到精通的实用指南
本文围绕C#的System.Text.Json库展开,介绍其是.NET Core 3.0及后续版本内置的高性能JSON序列化器,对比了与其他JSON库的优势。阐述使用前的环境要求和安装导入方法,讲解基本的序列化和反序列化操作,还介绍了进阶技巧、实际应用案例以及常见问题解决办法。
步、步、为营
3399
System.Text.Json输出的 json 中文、符号被编码(乱码)
本文介绍了如何在System.Text.Json中避免中文等非ASCII字符在序列化时被转义,提供了使用Unicode范围、指定字符和使用UnsafeRelaxedJsonEscaping编码器的解决方案,以及相关编码类和属性的应用实例。
胡老汉
9365
4个维度Newtonsoft.Json VS System.Text.Json,谁才是.NET的JSON王者?
本文通过科学对比和代码实战,深入探讨了.NET中Newtonsoft.JsonSystem.Text.Json两大JSON库的性能、功能及适用场景。Newtonsoft.Json以其强大的功能和良好的兼容性,适合老项目和复杂场景;而System.Text.Json则以性能优化和轻量级特性,更适合现代.NET Core项目和高性能需求。
墨瑾轩
893
System.Text.Json 嵌套深度问题
文章介绍了在开发中遇到System.Text.Json处理深度嵌套JSON时的循环检测异常,提供了两种解决方案一是切换回Newtonsoft.Json配置循环引用处理,二是直接调整System.Text.Json的SerializerOptions以支持更多嵌套层级。
1119
使用.Net6中的System.Text.Json遇到几个常见问题解决方案
本文介绍了如何在.NetCore中使用System.Text.Json解决字符编码问题,避免非ASCII字符转义,并处理对象套娃递归,提供实例和配置方法。
zls365365
7380
JSON序列化-System.Text.Json
本文深入探讨了.NET Core中System.Text.Json的功能与应用技巧,包括序列化、反序列化、属性控制、日期格式化等,旨在帮助开发者更好地掌握JSON处理。
1597
.NET Core 3.0 System.Text.Json 和 Newtonsoft.Json 行为不一致问题解决办法
探讨.NETCore3.0内置JSON库(System.Text.Json)与Newtonsoft.Json在序列化行为上的差异,尤其是在处理中文和特殊字符时的表现,并提供了解决方案。
dotNET跨平台
5337
【C#】System.Text.Json
System.Text.Json是.NET Core 3.0及以上版本中的高性能JSON处理库,提供序列化与反序列化功能,适用于.NET应用程序。相比Json.NET,它具有更好的性能和更低的内存占用。
软泡芙
1641
C# .NetCore 中使用 System.Text.Json 序列化 JSON 示例
本文深入探讨在C#中使用System.Text.Json库进行JSON序列化。介绍了导入命名空间、定义类和创建对象列表,展示默认序列化及使用JsonSerializerOptions控制序列化,如美观打印、忽略空值、自定义属性名称大小写等,还讲解处理大小写敏感、循环引用等问题
hefeng_aspnet
5661
Teams Bot 如何使用新的 System.Text.Json
本文探讨了在将LuckyDraw代码升级到.NET Core 3.1后,尝试使用System.Text.Json库替换Newtonsoft.Json时遇到的问题。尽管System.Text.Json性能更优,但Teams Bot SDK仍依赖于Newtonsoft.Json。由于SDK中Activity类的属性使用了Newtonsoft.Json的特性,导致在使用System.Text.Json进行序列化和反序列化时出现不匹配。为解决问题,开发者需要在与SDK交互时手动切换到Newtonsoft.Json进行序列化和反序列化操作,期待SDK能尽快兼容新Json库。
Tony.X
3250
C# JSON解析全攻略从Newtonsoft.JsonSystem.Text.Json性能实战
本文深入对比C#中Newtonsoft.JsonSystem.Text.Json两大JSON处理库,涵盖序列化/反序列化、动态JSON处理(JsonDocument/JsonNode)、自定义JsonConverter、源码生成器性能优化等核心技术。重点分析选型策略、性能差异、循环引用与多态反序列化等高频问题,并通过配置读取器实战演示高性能、健壮的JSON解析方案。
weixin_34037173
949
Newtonsoft.Json vs System.Text.Json:C# JSON处理库全面对比(2023最新版)
本文对比C#中两大主流JSON处理库:System.Text.Json(.NET原生、高性能、严格模式)与Newtonsoft.Json(功能丰富、灵活宽松)。涵盖性能基准(UTF-8直操作vs反射)、核心特性差异(如缺失属性处理)、迁移路径(渐进式替换、兼容包、转换器重构)、场景化决策树(新项目首选前者,遗留系统可延续后者),并强调源码生成、JsonSerializerOptions复用及安全反序列化等最佳实践。
星辰回声
871
.NET 6新特性 | System.Text.Json功能改进
在.NET 6.0中,JSON处理库System.Text.Json有显著改进。它取代了Newtonsoft.Json,具有性能提升、API简洁、兼容性强等优势。还引入忽略循环引用、序列化和反序列化通知等新特性。与Newtonsoft.Json相比,它性能更好、内置支持且集成度高,是处理JSON数据的强大工具。
夏子曦
1489
C# JSON序列化实战:System.Text.Json与Newtonsoft.Json深度对比与性能优化
本文深入对比System.Text.Json与Newtonsoft.Json在C#中的核心能力,涵盖性能、功能、配置灵活性及适用场景;重点解析System.Text.Json的定制序列化、异步处理、源生成器优化,并针对日期格式、循环引用、动态JSON、枚举转换及大型JSON内存陷阱提供实战避坑方案,强调类型安全、性能调优与工程实践平衡。
weixin_34174105
362
System.Text.Json类库进行json转化时ValueKind:Object问题
博客介绍了使用System.Text.Json库而非Newtonsoft.Json库时可能遇到的问题解决办法。包括因无明确类型基础类型导致的转换错误,可写对象Json转换器类;webapi接口时间属性格式问题,需定义时间Json转换器;枚举属性返回字符串问题,可进行相应配置并添加特性。
xk_hypothesis
1282
C# Text.Json.Deserialize 中文不能反序列化
在C#中使用Text.Json类库反序列化包含中文的JSON数据时,可能会遇到中文无法正确反序列化的问题。本文提供了三种解决方案指定正确的字符编码、设置全局编码以及检查JSON格式。
香山-小陈
C#中使用Json
本文详细介绍了C#中使用JSON的两种主要方法:System.Text.Json和Newtonsoft.Json。内容包括基本用法、高级功能、性能比较、安装引用以及常见问题处理。通过对比两种库的适用场景,帮助开发者根据项目需求选择合适的JSON处理库。
kxy0616
在visio studio中怎么用C#语言创建json文件
本文介绍了如何在Visual Studio中使用C#语言创建JSON文件。首先创建一个C#控制台应用程序项目,然后添加Newtonsoft.Json库或使用.NET内置的System.Text.Json。接着定义数据模型,序列化对象为JSON字符串,并将字符串写入文件。文章还提供了使用System.Text.Json和Newtonsoft.Json两种方法的详细步骤,并强调了注意事项。
苌忪桃李
System.Text.Json.JsonSerializer.Serialize 序列化时不做转义
qq_26351717
【C#中的现代JSON处理】:Json.NET与System.Text.Json对比
SW_孙维
C#的 System.Text.Json.JsonSerializer.Serialize时不能显示中文
qq_24410559
System.Text.Json 中的 JavaScriptEncoder 有哪些内置选项?
2401_86106623
C# JSON文件读写全解析System.Text.Json到Newtonsoft.Json实战指南
用户6162018649
C#里用Newtonsoft.Json替换System.Text.Json时,序列化和配置要怎么对应调整?
Hero_zwx
System.Text.Json怎么把对象转成JSON又转回来?中文和时间格式怎么处理?
侍伟&Peter