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…

jQuery获取及设置单选框,多选框,文本框内容

在工作中,text,radio,checkbox,select在开发过程中是必不可少的一部分.在开发过程中经常要处理页面表单元素. Eg: 在复选框checkBox中获取checked的value值,来触发和调用其它页面表单元素,制作互动性更强更友好的用户体验. jQuery通过元素$(#id)产生一个object对象,通过对获…

js局部打印

因为需要用到这个东西&#xff0c;所以很无耻的拾人牙慧&#xff0c;收在博客里了~ ?<!DOCTYPE html><html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title>无标题文档</title>&l…

c语言出勤成绩,C语言课程设计学生考勤系统文档推荐 (10页)-原创力文档

C语言程序设计课程设计报告设计题目&#xff1a; 学生考勤系统设计专 业 微电子科学与工程班 级 微电 131学 生 赵 杨 怡指导教师年 学期设计任务&#xff1a; C 语言课程设计任务书 10题目&#xff1a;学生考勤系统设计功能&#xff1a;学生考勤系统应包含各班学生的全部信息。…

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;经典科普电视节目《走近科学》迎来最…

vsftpd使用方法小结、Linux安装JDK出现“NoClassDefFoundError: /Object”的解决方案、ubuntu 12.04安装jdk

vsftpd使用方法小结vsftpd 是一个 UNIX 类操作系统上运行的服务器的名字&#xff0c;它可以运行在诸如 Linux, BSD, Solaris,HP-UX 以及 IRIX 上面。它支持很多其他的 FTP 服务器不支持的特征。比如&#xff1a; 非常高的安全性需求带宽限制良好的可伸缩性创建虚拟用户的可能性…

从函数中返回多个值的方法

There are several ways to return multiple values from functions. In this topic, we’re going to look over the 5 most common techniques to pass 2 or more values from functions. The 5 techniques are: 1、Returning variables in Global scope 2、Returning a Coll…

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;做一…

js时间-价格-排序案例____冒泡排序实例

js 时间-价格-排序&#xff0c;静态页面排序案例冒泡排序实例 在项目中用到的一个例子&#xff0c;分享一下。 var sort {sortdata : , //排序之前必须先填充原始数据 //来源我的博客&#xff1a;http://yijianfengvip.blog.163.com/blog/static/1752734322011102145823/…

Horspool 字符串快速查找算法

Horspool算法是后缀搜索算法&#xff0c;对于每个文本搜索窗口&#xff0c;将窗口内的最后一个字符与模式串(needle)的最后一个字符进行比较。如果相等&#xff0c;则继续从后向前验证其他字符&#xff0c;直到完全相等或者某个字符不匹配。当遇到字符不匹配的情况时就需要将搜…

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

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

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

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