You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让.NET 6的System.Text.Json按UTF-8解析转义字符?

解决System.Text.Json解析Facebook备份JSON时的UTF-8转义字符乱码问题

Facebook备份的JSON文件中,特殊字符被转换成了UTF-8字节的十六进制转义序列(比如é的UTF-8字节0xC3 0xA1被写成\u00c3\u00a1),但System.Text.Json默认会将\uXXXX转义解析为UTF-16代码单元,导致出现Tamás这类乱码。要解决这个问题,需要自定义一个JsonConverter<string>来手动处理这种非标准的转义格式。

自定义转换器实现

这个转换器会遍历字符串,将\uXXXX格式的转义序列还原为UTF-8字节,最后统一用UTF-8解码得到正确字符串:

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

public class Utf8EscapedStringConverter : JsonConverter<string>
{
    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var rawString = reader.GetString();
        if (rawString is null) return null;

        var utf8Bytes = new List<byte>();
        int index = 0;

        while (index < rawString.Length)
        {
            // 识别\uXXXX格式的转义序列
            if (rawString[index] == '\\' && index + 1 < rawString.Length && rawString[index + 1] == 'u')
            {
                // 提取四位十六进制字符并转换为字节
                if (index + 5 <= rawString.Length &&
                    byte.TryParse(rawString.Substring(index + 2, 2), System.Globalization.NumberStyles.HexNumber, null, out var utf8Byte))
                {
                    utf8Bytes.Add(utf8Byte);
                    index += 6; // 跳过整个\uXXXX序列(\u + 4位十六进制,共6个字符)
                    continue;
                }
            }

            // 普通字符直接转换为UTF-8字节
            utf8Bytes.AddRange(Encoding.UTF8.GetBytes(rawString[index].ToString()));
            index++;
        }

        return Encoding.UTF8.GetString(utf8Bytes.ToArray());
    }

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        // 序列化时沿用默认逻辑,若需要匹配Facebook格式可自行扩展
        writer.WriteStringValue(value);
    }
}

使用方式

有两种方式应用这个转换器:

1. 针对单个属性添加

在需要处理的字符串属性上标记[JsonConverter]特性:

class Msg
{
    [JsonPropertyName("sender_name")]
    [JsonConverter(typeof(Utf8EscapedStringConverter))]
    public string SenderName { get; set; }
}

2. 全局注册转换器

如果所有字符串属性都需要处理,可在JsonSerializerOptions中全局添加:

public class Program
{
    public static void Main()
    {
        var data = @"{
            ""sender_name"": ""Tam\u00c3\u00a1s""
        }";

        var options = new JsonSerializerOptions();
        options.Converters.Add(new Utf8EscapedStringConverter());

        var msg = JsonSerializer.Deserialize<Msg>(data, options);
        Console.WriteLine(msg.SenderName); // 输出:Tamás
    }
}

原理说明

  • Facebook的转义方式不符合JSON标准:JSON规范中\uXXXX表示UTF-16代码单元,而Facebook是将UTF-8字节逐个转义。
  • 自定义转换器通过解析\uXXXX序列得到原始UTF-8字节,再用UTF-8解码,从而还原出正确的特殊字符。

内容的提问来源于stack exchange,提问作者quywsx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:10:27