System.Text.Json输出的 json 中文、符号被编码(乱码)

15 篇文章 0 订阅

默认情况下,序列化程序会转义所有非 ASCII 字符。 即,会将它们替换为 \uxxxx,其中 xxxx 为字符的 Unicode 代码。

例如,如果以下 JSON 中的 sign 属性为中文还有符号等 "中文 Holle Word abc 1+1<1>1&1'1$",则SingModel对象会进行序列化,如以下示例中所示:

//转Json之前
{ 
    ver = "1.0", 
    identifier = "admin", 
    appid = 10000,
    sign = "中文 Holle Word abc 1+1<1>1&1'1$" 
}
//System.Text.Json转Json之后
{ 
    ver = "1.0", 
    identifier = "admin", 
    appid = 10000,
    sign = "\u4E2D\u6587 Holle Word abc 1\u002B1\u003C1\u003E1\u00261\u00271$" 
}

解决办法:

一、序列化语言字符集

若要序列化一种或多种语言的字符集而不进行转义,请在创建 System.Text.Encodings.Web.JavaScriptEncoder 的实例时指定 Unicode 范围,如以下示例中所示:

using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;

options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic)
};
jsonString = JsonSerializer.Serialize(singModel, options);

此代码不转义西里尔文或希腊语字符。 如果 Summary 属性设置为西里尔文 жарко,则 WeatherForecast 对象会进行序列化,如以下示例中所示:

若要序列化所有语言集而不进行转义,请使用 UnicodeRanges.All
想了解其他的语言集,请移步:UnicodeRanges类 

二、序列化特定字符

一种替代方法是指定要允许的单个字符,而不进行转义。 下面的示例仅序列化 жарко 的前两个字符:

using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;

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

三、序列化所有字符(建议使用这种方式)

若要最大程度地减少转义,可以使用 JavaScriptEncoder.UnsafeRelaxedJsonEscaping,如以下示例中所示:

using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;

options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);

注意

与默认编码器相比,UnsafeRelaxedJsonEscaping 编码器在允许字符通过而不进行转义方面更加宽松:

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

仅当知道客户端将生成的有效负载解释为 UTF-8 编码的 JSON 时,才使用不安全编码器。 例如,如果服务器在发送响应标头 Content-Type: application/json; charset=utf-8,则可以使用它。 永远不允许将原始 UnsafeRelaxedJsonEscaping 输出发出到 HTML 页面或 <script> 元素。

参考文档

1、如何使用 System.Text.Json 自定义字符编码 | Microsoft Docs

2、UnicodeRanges 类 (System.Text.Unicode) | Microsoft Docs

3、如何使用 System.Text.Json 自定义字符编码 | Microsoft Docs

4、JavaScriptEncoder.UnsafeRelaxedJsonEscaping 属性 | Microsoft Docs

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡老汉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值