如何禁用System.Text.Json反序列化时Unicode转义字符自动解码
问题说明
使用System.Text.Json执行反序列化操作时,针对如下JSON结构:
{ "name": "\ud092\u00d0" }
默认调用JsonSerializer.Deserialize方法会自动将\uXXXX格式的Unicode转义序列解码为对应实际字符,现需要禁用该自动解码行为,获取与原始JSON文本完全一致的字符串值\ud092\u00d0。
实现方法
System.Text.Json没有提供全局关闭Unicode转义自动解码的配置开关,可通过以下两种方式实现需求:
方法1:自定义JSON字符串转换器(适合全量/指定字段反序列化场景)
通过自定义JsonConverter<string>实现,读取值时直接获取JSON原始文本,不触发默认的转义解码逻辑:
- 编写自定义转换器代码
using System.Text.Json; using System.Text.Json.Serialization; public class KeepRawEscapeStringConverter : JsonConverter<string> { public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.String) throw new JsonException("当前令牌不是字符串类型"); // 获取JSON中该字段的原始文本(默认带首尾双引号包裹) string rawText = reader.GetRawText(); // 去除首尾的JSON字符串包裹双引号 if (rawText.Length >= 2 && rawText[0] == '"' && rawText[^1] == '"') { rawText = rawText.Substring(1, rawText.Length - 2); } return rawText; } public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { // 序列化逻辑可按需调整,默认直接写入字符串值即可 writer.WriteStringValue(value); } }
- 反序列化时使用该转换器
- 全局生效:将转换器加入
JsonSerializerOptions的转换器集合
var options = new JsonSerializerOptions(); options.Converters.Add(new KeepRawEscapeStringConverter()); // 替换为实际的模型类型即可 var obj = JsonSerializer.Deserialize<YourModel>(jsonStr, options);
- 仅指定字段生效:给目标模型的对应属性添加特性,不影响其他字符串字段的默认解码逻辑
public class YourModel { [JsonConverter(typeof(KeepRawEscapeStringConverter))] public string name { get; set; } }
方法2:通过JsonDocument读取原始值(适合临时读取单个字段场景)
如果不需要完成全量对象反序列化,只是要读取指定字段的原始转义值,可以直接用JsonDocument解析后获取原始文本:
using JsonDocument doc = JsonDocument.Parse(jsonStr); JsonElement nameProp = doc.RootElement.GetProperty("name"); string rawValue = nameProp.GetRawText(); // 去除首尾双引号 if (rawValue.Length >= 2 && rawValue[0] == '"' && rawValue[^1] == '"') { rawValue = rawValue.Substring(1, rawValue.Length - 2); } // rawValue即为原始的\ud092\u00d0
注意事项
- 不要在读取逻辑中调用
reader.GetString()或者对应JsonElement的GetString()方法,该方法内部会自动完成所有转义序列的解码,无法拿到原始转义文本。 - 以上实现会保留字符串中所有类型的转义序列(包括
\n、\"、\t等),不会做任何自动解码。
内容的提问来源于stack exchange,提问作者Nikolay Kostov
相关产品推荐
相关产品推荐

