我有一些JSON文件(facebook备份),是UTF-8编码,但特殊字符被转义。转义字符也是UTF-8编码,但在十六进制格式。例如:
{
"sender_name": "Tam\u00c3\u00a1s"
}
我想使用System.Text.Json.JsonSerializer进行反序列化,问题是它将转义的十六进制解释为UTF-16字符,因此它将被反序列化为“Tamás”,而不是它应该的“Tamás”。
要重现的代码:
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
class Msg
{
[JsonPropertyName("sender_name")]
public string SenderName { get; set; }
}
public class Program
{
public static void Main()
{
var data = @"{
""sender_name"": ""Tam\u00c3\u00a1s""
}";
var msg = JsonSerializer.Deserialize<Msg>(data);
Console.WriteLine(msg.SenderName);
}
}
我可以改变序列化器把它解释成UTF-8吗?
2条答案
按热度按时间afdcj2ne1#
这里的问题是JSON的发送者在字符串常量中为
á
的数字转义码指定了错误的值\u00c3
和\u00a1
。\uXXXX
转义序列的含义由JSON Proposal和JSON标准指定。它的定义是XXXX是字符的“4 HEXDIG”UTF-16 Unicode码点值[1]。对于á
,它是\u00E1
。相反,JSON文件的提供商(显然是Facebook的“备份数据功能”)使用UTF-8十六进制值作为\uXXXX
转义序列,而不是标准要求的UTF-16。没有内置的方法来告诉System.Text.Json(或Json .NET)
\uXXXX
转义序列使用了非标准值,但是Utf8JsonReader
通过ValueSpan
和ValueSequence
属性提供了对底层原始字节流的访问,因此可以创建一个自定义JsonConverter<string>
,该JsonConverter<string>
执行必要的解码和取消转义。首先,创建以下转换器:
现在你可以
注:
string
之前,应该修复不正确的转义值,因为一旦解码和取消转义完成,转义序列的存在与否就会丢失。Encoding.UTF8.GetDecoder()
返回的解码器进行块解码可能性能更好,而不是像这个原型那样逐个字节地解码。演示小提琴here。
[1]不在基本多语言平面中的字符应使用两个连续的转义序列,例如
\uD834\uDD1E
lqfhib0f2#
试试这个代码
也可以添加JSON构造函数