System.Text.Json 中的字符编码

System.Text.Json 中的字符编码

Intro

默认的 System.Text.Json 序列化的时候会把所有的非 ASCII 的字符进行转义,这就会导致很多时候我们的一些非 ASCII 的字符就会变成 \uxxxx 这样的形式,很多场景下并不太友好,我们可以配置字符编码来解决被转义的问题

Sample

首先来看一个简单的示例:

var testObj = new
{Name = "小明",Age = 10
};
WriteLine(JsonSerializer.Serialize(testObj));

输出结果如下:

{"Name":"\u5C0F\u660E","Age":10}

可以看到,我们的中文没有直接显式出来,而是被转义了,这可读性一下子就大打折扣了,接着我们来尝试让他工作

在我们序列化的时候,可以指定一个 JsonSerializeOptions,而这个 JsonSerializeOptions 中有一个 Encoder 我们可以用来配置支持的字符编码,不支持的就会被转义,而默认只支持 ASCII 字符

我们可以配置 Encoder 来支持中文,如下所示:

WriteLine(JsonSerializer.Serialize(testObj, new JsonSerializerOptions()
{Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, new UnicodeRange(0x4E00, 8000))
}));WriteLine(JsonSerializer.Serialize(testObj, new JsonSerializerOptions()
{Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs)
}));WriteLine(JsonSerializer.Serialize(testObj, new JsonSerializerOptions()
{Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
}));

我们可以通过 JavaScriptEncoder.Create 来自定义支持的字符范围,要指定一个 Unicode 范围

System.Text.Unicode.UnicodeRanges 这个静态类中定义了一些静态属性来比较方便的使用各个语言对应的字符集范围,当然如果你明确的知道字符从哪里开始,有多个个字符也可以自定义,如上面的第一种方式,但是这种不是特别推荐,因为你知道的范围并不一定是最准确的而且可能会有变更

推荐还是直接使用 UnicodeRanges 里定义好的字符集,如第二种方式,第二种方式这里的 UnicodeRanges.CjkUnifiedIdeographs 就包含了中文字符,去网上查了一下这个 CjkUnifiedIdeographs 代表中文(Chinese)、日文(Japanese )、韩文(Korean)的字符集合

中日韩统一表意文字(英语:CJK Unified Ideographs),也称统一汉字、统汉码(英语:Unihan),目的是要把分别来自中文、日文、韩文、越南文、壮文、琉球文中,起源相同、本义相同、形状一样或稍异的表意文字,在ISO 10646及万国码标准赋予相同编码。

如果你不确定是哪种字符集或者有全球化的需求,可以直接使用 UnicodeRanges.All 来支持所有的字符,如上面第三种方式

上面的示例输出结果如下:

{"Name":"小\u660E","Age":10}
{"Name":"小明","Age":10}
{"Name":"小明","Age":10}

除此之外还有一个地方可能会需要,对于一些包含 html 标签的文本即使指定了所有字符集也会被转义,这是出于安全考虑。如果觉得不需要转义也可以配置,配置使用 JavaScriptEncoder.UnsafeRelaxedJsonEscaping 即可,示例如下:

var testObj = new
{Name = "小明",Age = 10,Description = "<h1>这是标题</h1>"
};WriteLine(JsonSerializer.Serialize(testObj, new JsonSerializerOptions()
{Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
}));WriteLine(JsonSerializer.Serialize(testObj, new JsonSerializerOptions()
{Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
}));

输出结果如下:

{"Name":"小明","Age":10,"Description":"\u003Ch1\u003E这是标题\u003C/h1\u003E"}
{"Name":"小明","Age":10,"Description":"<h1>这是标题</h1>"}

Console Logging

之前曾经介绍过 JsonLogging .NET5  的一个新特性,可以参考 .net 5.0 中的 JsonConsoleJsonConsole 来格式化 Console 的日志为 Json,使用默认的配置然后会发现日志中会有很多这种 \uxxxx 的东西,看起来怪怪的,如下图所示:

39ba11a6016eddd82798e30e0fb7ee9c.png

后来测试发现默认支持的字符集也只是 ASCII 字符,而且有些字符会出于安全考虑也会转义,微软也是支持配置  Encoder 的,不过不是 JsonSerializeOptions, 而是 JsonWriterOptions,我们可以在注册 JsonConsole 的时候配置 Encoder,示例如下:

var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddJsonConsole(options =>
{options.JsonWriterOptions = new JsonWriterOptions{Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping};
});

这里我们直接使用比较宽松的转义规则,因为我们的场景是日志不会直接渲染在页面上,所以个人觉得不必要求的太严格

加了上面的配置之后的日志如下:

e371d5bd720781c839b238fb122074aa.png

这样的日志看起来就舒服多了,可读性也会更好一些

More

在指定 Unicode 字符集范围的时候需要把 UnicodeRanges.BasicLatin 也加上,其他的字符串没有包含基本的 ASCII 字符,否则基本的 ASCII 字符也会被转义

你也可以通过 TextEncoderSettings 来配置只支持的字符,示例如下:

var encoderSettings = new TextEncoderSettings();
encoderSettings.AllowCharacters('\u0436', '\u0430');
encoderSettings.AllowRange(UnicodeRanges.BasicLatin);
var options = new JsonSerializerOptions
{Encoder = JavaScriptEncoder.Create(encoderSettings)
};
var jsonString = JsonSerializer.Serialize(weatherForecast, options);

针对 JavaScriptEncoder.UnsafeRelaxedJsonEscaping 的使用需要注意安全问题

  • 它不转义 HTML 敏感字符,如 <>&'

  • 它不提供任何针对 XSS 或信息泄露攻击(如客户端和服务器在字符集方面不一致所可能导致的攻击)的额外深度防御保护。

不要将原始 UnsafeRelaxedJsonEscaping 序列化的结果用到 HTML 页面或 <script> 元素

References

  • https://github.com/WeihanLi/SparkTodo/blob/master/SparkTodo.API/Program.cs#L22

  • https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-character-encoding?WT.mc_id=DT-MVP-5004222

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/JsonSample/SystemTextJsonSample/EncoderSample.cs

  • https://docs.microsoft.com/zh-cn/dotnet/standard/serialization/system-text-json-character-encoding?WT.mc_id=DT-MVP-5004222

  • https://en.wikipedia.org/wiki/CJK_Unified_Ideographs

  • .net 5.0 中的 JsonConsole

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

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

相关文章

maven3安装和使用笔记

2019独角兽企业重金招聘Python工程师标准>>> 1、下载 http://maven.apache.org/download.cgi 2、解压 3、配置环境变量 M2_HOME D:\program\apache-maven-3.3.3 Path : %M2_HOME%\bin 4、验证是否成功 打开命令行窗口&#xff0c;输入mvn -version&#xff0c;显示…

数学,原来可以这么美!

全世界只有3.14 % 的人关注了爆炸吧知识法国著名艺术家罗丹曾说&#xff1a;世界中从不缺少美&#xff0c;而是缺少发现美的眼睛。对于我们的眼睛&#xff0c;不是缺少美&#xff0c;而是缺少发现。在艺术者眼中&#xff0c;一切都是美的&#xff0c;因为他锐利的慧眼&#xff…

Hadoop的伪分布安装 hadoop的核心思想

Hadoop的伪分布安装hadoop的安装分为本地模式、伪分布模式、集群模式。本地模式是运行在本地&#xff0c;只负责存储&#xff0c;没有计算功能&#xff0c;本书不讲述。伪分布模式是在一台机器上模拟分布式部署&#xff0c;方便学习和调试。集群模式是在多个机器上配置hadoop&a…

lambda与内置函数

2019独角兽企业重金招聘Python工程师标准>>> 学习条件运算时&#xff0c;对于简单的 if else 语句&#xff0c;可以使用三元运算来表示&#xff0c;即 # 普通条件语句 if 1 1:name eddy else:name yys# 三元运算 name eddy if 1 1 else yys lambda表达式 # ###…

年仅21岁,干掉6位诺贝尔奖得主,被誉为科学界最强杀手,却惨被人骂成一个笑话...

全世界只有3.14 % 的人关注了爆炸吧知识在刚过去的国庆假期期间&#xff0c;超模君总是在不经意间看到许多诡异的小视频&#xff01;而一提起充满诡异气息的视频&#xff0c;《走近科学》这档节目堪称经典&#xff01;然而在去年&#xff0c;经典科普电视节目《走近科学》迎来最…

python 字典操作

假设字典为dics {0:a, 1:b, c:3} 1.从字典中取值&#xff0c;当键不存在时不想处理异常 [方法] dics.get(key, not found) [例如] [解释] 当键key不存在是&#xff0c;打印not found(即想要处理的信息)&#xff0c;当存在是输出键值。 【其他解决方案一】 if key in dics: …

Web实时通信,SignalR真香,不用愁了

前言对于B/S模式的项目&#xff0c;基础的场景都是客户端发起请求&#xff0c;服务端返回响应结果就结束了一次连接&#xff1b;但在很多实际应用场景中&#xff0c;这种简单的请求和响应模式就显得很吃力&#xff0c;比如消息通知、监控看板信息自动刷新等实时通信场景&#x…

四位数码管树莓派c语言,用树莓派和四位数码管模块做一个时钟

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;预备知识如图&#xff0c;这是一个4位数码管模块&#xff0c;由两片 74HC595 级联控制&#xff0c;引脚如图&#xff0c;从上到下&#xff0c;分别为VCC(3.3V/5V),…

这5部不容错过的超高评价纪录片,带你领略地球的魅力!

全世界只有3.14 % 的人关注了爆炸吧知识地球是茫茫宇宙星系中唯一生机勃勃万物生存的星球&#xff0c;它是瞬息万变、充满自然奇观的世界。50多亿年来&#xff0c;地球在日复一日、沧海桑田地变化着。今天就给大家带来最顶尖的BBC地球科普纪录片&#xff0c;最盛大的听觉盛宴&a…

【转】Android 带checkbox的listView 实现多选,全选,反选 -- 不错

原文网址&#xff1a;http://blog.csdn.net/onlyonecoder/article/details/8687811 Demo地址&#xff08;0分资源&#xff09;&#xff1a;http://download.csdn.net/detail/onlyonecoder/5154352 由于listview的一些特性&#xff0c;刚开始写这种需求的功能的时候都会碰到一些…

第三方QQ、微博登陆

一定要把token uid 这些参数搞明白是干什么的 第一种方法是转的 &#xff08;通过javascript来调用&#xff09; 最近接触了一些第三方登陆的东西&#xff0c;弄的真是一个头&#xff0c;两个大>.< 今天&#xff0c;终于把腾讯第三方登陆调试通了&#xff0c;做一…

由NTC电阻值 计算温度 C语言,高精度NTC测温电路设计及电阻值计算

什么是NTCNTC是热敏电阻&#xff0c;其电阻值对温度变化敏感&#xff0c;在不同的温度下&#xff0c;可以呈现不同的电阻值。热敏电阻有两类&#xff0c;一类是负温度系数电阻(NTC)&#xff0c;温度增加时&#xff0c;电阻值降低&#xff0c;另一类是正温度系数电阻(PTC)&#…

史上最被低估的两个学科!它们远比你想的更重要!

▲点击查看哈佛大学本杰明教授曾说&#xff1a;“越是到了高等教育的阶段&#xff0c;人们就越重视从历史中总结经验&#xff0c;尤其是精英阶层。很多人都想好好读读历史&#xff0c;但是一直以来&#xff0c;读历史都有一个问题&#xff1a;看着满满都是字的大部头&#xff0…

这是你想象中的泳池美女吗?爱了吗?

1 小手一插&#xff0c;谁都不爱▼2 玩滑板讲究顺其自然哪里摔倒&#xff0c;就在哪里跪下▼3 陪老婆待产的企鹅们▼4 这就是米其林三星级的地摊吗&#xff1f;▼5 年度最好的送男友礼物▼6 张雨绮表演内心戏全程▼7 说&#xff01;这种极品西瓜哪里有卖&#xff1f;▼你…

Abp Vnext Vue3 的版本实现

Abp Vnext Pro 的 Vue3 实现版本 开箱即用的中后台前端/设计解决方案开始Github地址文档地址演示地址系统功能[x] 用户管理[x] 角色管理[x] 审计日志[x] 后台任务[x] 集成事件[x] IdentityServer4[x] 客户端管理[x] Api 资源管理[x] ApiScope 管理[x] Identity 资源管理[x] Sin…

struts2配置中Action的name 和package的name和namespace作用

2019独角兽企业重金招聘Python工程师标准>>> struts2配置中Action的name 和package的name和namespace是什么作用 在struts2 struts.xml 配置中 <package name"ajax" extends"json-default" namespace"/json"> <action na…

【译】Tablix指南----通向报表服务的阶梯系列(四)

“Ah ha,发现你了&#xff01;”你的经理突然从桌子后面的假花旁冒出来&#xff0c;发出胜利的叫声。你沮丧地转过头看着经理。 “我已经创建了一个基本报表&#xff0c;并抓取了一些数据&#xff0c;我正打算-”你在他打断你之前快速的解释着。 “赶紧做完就好&#xff0c;大B…

熊吃人该不该杀?这头3米高的大熊吃了7个人,还在洞里藏了很多女人用的东西.........

全世界只有3.14 % 的人关注了爆炸吧知识10月18日&#xff0c;有网友爆料称“上海野生动物园猛兽区一饲养员遭群熊撕扯”。随后&#xff0c;上海野生动物园证实&#xff0c;该饲养员目前已身亡。据悉&#xff0c;他才27岁&#xff0c;还没成家。从网上发布的现场视频来看&#x…

还在纠结Dapper或者EF Core?不妨试试“混合ORM”--RepoDb

在.NET世界中&#xff0c;提到ORM&#xff0c;最常用的是下面2个&#xff1a;Dapper&#xff0c;通过提供IDbConnection的扩展方法来查询数据库。它的优点在于可以轻松地执行参数化查询&#xff0c;将结果转化为对象&#xff1b;非常高效&#xff0c;在速度方面拥有micro-ORM之…

使用 PHP 7 给 Web 应用加速

PHP 20周年了&#xff01;&#xff1f;&#xff1f; PHP 首发通告&#xff0c;1995年6月8日 发布于 COMP.INFOSYSTEMS.WWW.AUTHORING.CGI 主题&#xff1a;正式宣布&#xff1a;个人主页工具&#xff08;Personal Home Page Tools&#xff09;正式宣布个人主页工具&#xff08;…