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

如何创建自定义Json.NET转换器,在序列化MergeResponse对象时保留第三方API原始JSON内容

如何创建自定义Json.NET转换器,在序列化MergeResponse对象时保留第三方API原始JSON内容

嘿,这个场景我之前也碰到过,第三方API悄悄加字段的情况真的挺闹心!不过用自定义Json.NET转换器完全能解决问题——直接把API返回的原始JSON完整嵌到最终的序列化结果里,不管你的类有没有同步更新字段。下面是具体的实现步骤和代码:

第一步:实现自定义Json转换器

我们要创建一个继承自JsonConverter的转换器,专门处理MergeResponse的序列化逻辑。核心思路是:序列化时先处理MessageId这类固定属性,再把两个API的原始JSON解析成JSON节点,替换掉原本类序列化后的内容。

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;

public class MergeResponseConverter : JsonConverter
{
    // 仅处理MergeResponse类型的序列化
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(MergeResponse);
    }

    // 我们只需要序列化能力,不需要反序列化,所以返回false
    public override bool CanRead => false;

    // 反序列化方法无需实现,直接抛出异常提示
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("此转换器仅用于MergeResponse对象的序列化操作");
    }

    // 核心序列化逻辑
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var mergeResponse = value as MergeResponse;
        if (mergeResponse == null)
        {
            serializer.Serialize(writer, value);
            return;
        }

        // 1. 先将MergeResponse转为JObject,自动处理已知固定属性(比如MessageId)
        var jObject = JObject.FromObject(mergeResponse, serializer);

        // 2. 替换ApiResponse1为原始JSON对应的JToken
        if (!string.IsNullOrEmpty(mergeResponse.ApiResponse1?.OrigJson))
        {
            try
            {
                var api1OriginalJson = JToken.Parse(mergeResponse.ApiResponse1.OrigJson);
                jObject["ApiResponse1"] = api1OriginalJson;
            }
            catch (JsonReaderException ex)
            {
                // 处理原始JSON格式错误的情况,可根据需求调整逻辑(比如保留类序列化结果或抛出异常)
                Console.WriteLine($"ApiResponse1原始JSON解析失败: {ex.Message}");
            }
        }

        // 3. 同样处理ApiResponse2的原始JSON
        if (!string.IsNullOrEmpty(mergeResponse.ApiResponse2?.OrigJson))
        {
            try
            {
                var api2OriginalJson = JToken.Parse(mergeResponse.ApiResponse2.OrigJson);
                jObject["ApiResponse2"] = api2OriginalJson;
            }
            catch (JsonReaderException ex)
            {
                Console.WriteLine($"ApiResponse2原始JSON解析失败: {ex.Message}");
            }
        }

        // 4. 将处理好的JObject写入到输出流
        jObject.WriteTo(writer);
    }
}

第二步:使用自定义转换器序列化

在序列化MergeResponse时,只需要在SerializeObject方法中指定我们的转换器即可:

// 序列化时传入自定义转换器
string finalJson = JsonConvert.SerializeObject(mergeResp, 
    Newtonsoft.Json.Formatting.Indented, 
    new MergeResponseConverter());

方案优势说明

  • 不破坏原有类结构:OrigJson依然用[JsonIgnore]标记,不会被默认序列化逻辑干扰
  • 完整保留原始字段:直接将API返回的原始JSON解析后嵌入结果,不管你的ApiResponse1/ApiResponse2类有没有定义对应字段
  • 容错性强:加入了原始JSON格式错误的处理逻辑,避免单个API的JSON问题导致整个序列化失败

额外小提示

如果后续需要调整属性的JSON键名(比如把MessageId改成小写的message_id),可以给MergeResponse的属性加上[JsonProperty("message_id")]特性,转换器会自动识别并应用这个配置。

备注:内容来源于stack exchange,提问作者m_collard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:04:31