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

在反序列化的JSON.NET对象中存储原始JSON字符串

实现Newtonsoft反序列化时保留原始JSON字符串到Message对象

看起来你已经选对了方案——自定义JsonConverter确实是实现这个需求的最优解。咱们把这个转换器补全,让它既能正确解析Type属性,又能把原始JSON字符串完整存到Original字段里。

完整的自定义JsonConverter实现

首先,咱们把MessageConverter写完整,它需要实现ReadJson(处理反序列化,这是你需求的核心)和WriteJson(处理序列化,可选但建议补全)两个方法:

public class MessageConverter : JsonConverter<Message>
{
    // 反序列化核心逻辑:从JSON字符串转Message对象时保存原始JSON
    public override Message ReadJson(JsonReader reader, Type objectType, Message existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 先把整个JSON读取成JToken,这样能拿到完整的原始JSON字符串
        JToken token = JToken.Load(reader);
        
        // 将JToken转为原始JSON字符串(用Formatting.None确保输出紧凑格式,和输入一致)
        string originalJson = token.ToString(Formatting.None);
        
        // 创建Message对象,传入原始JSON
        Message message = new Message(originalJson);
        
        // 从JToken里解析Type属性赋值给对象
        message.Type = token["Type"]?.ToString();
        
        return message;
    }

    // 序列化逻辑:如果需要把Message转回JSON,这里可以自定义输出格式
    public override void WriteJson(JsonWriter writer, Message value, JsonSerializer serializer)
    {
        // 方案1:直接序列化Type和Original两个属性
        JObject obj = new JObject();
        obj["Type"] = value.Type;
        obj["Original"] = value.Original;
        obj.WriteTo(writer);
        
        // 方案2:如果希望序列化时输出原始的Original JSON(而不是把它作为字符串),可以用下面的代码:
        // JToken originalToken = JToken.Parse(value.Original);
        // originalToken.WriteTo(writer);
    }
}

关键细节说明

  • ReadJson方法:通过JToken.Load(reader)读取整个JSON节点,再用ToString(Formatting.None)获取原始JSON字符串,确保和输入的格式一致(不会额外增加缩进)。然后调用你的构造函数初始化Message,再从JToken里提取Type属性赋值。
  • WriteJson方法:提供了两种方案,你可以根据需求选择:
    • 方案1:把Message的Type和Original作为两个独立字段输出JSON。
    • 方案2:直接输出Original里的原始JSON,相当于还原最初的输入(适合需要反向还原的场景)。

使用示例

现在你可以正常反序列化JSON字符串到Message对象,原始JSON会自动存在Original属性里:

// 示例JSON
string inputJson = "{\"Type\":\"Alert\",\"Content\":\"System update available\"}";

// 反序列化
Message msg = JsonConvert.DeserializeObject<Message>(inputJson);

// 验证结果
Console.WriteLine(msg.Type); // 输出:Alert
Console.WriteLine(msg.Original); // 输出:{"Type":"Alert","Content":"System update available"}

额外注意点

如果你的原始JSON输入带有缩进或者特殊格式,而你需要完全精确保留输入的每一个字符(包括空格、换行),可以修改ReadJson方法,直接读取JsonReader的原始值:

// 替代JToken.Load的方式,直接读取原始字符串
string originalJson = reader.Value.ToString();

不过这种方式只适合JSON是单个字符串的场景,大多数情况下用JToken的方式更可靠,因为它能处理复杂的JSON结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:29:46