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

如何在Newtonsoft JSON.Net反序列化前修改$type字段映射新旧类型?

解决JSON反序列化时$type类型替换的问题

我来帮你搞定这个类型映射的问题!你遇到的情况是常见的类型重构后JSON反序列化兼容问题,之前尝试JsonConverter没成功可能是没找对合适的实现方式,这里给你两种靠谱的解决方案:

方法一:使用SerializationBinder映射旧类型到新类型(推荐)

这种方式不需要修改原始JSON字符串,而是在反序列化过程中直接把旧的$type值映射到新的类型,是最优雅的长期解决方案。

实现步骤:

  1. 自定义一个SerializationBinder,用来处理类型的映射逻辑:
using Newtonsoft.Json;
using System;

public class CustomTypeBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        // 检测到旧类型名时,返回新类型
        if (typeName.Equals("TestProject.Classes.TestClass", StringComparison.Ordinal))
        {
            return typeof(TestClassNew);
        }
        
        // 其他类型保持原逻辑解析
        return Type.GetType($"{typeName}, {assemblyName}");
    }
}
  1. 反序列化时指定这个Binder:
// 你的原始JSON字符串
string originalJson = @"[ { ""$type"": ""TestProject.Classes.TestClass, TestProject"", ""Name"": ""TestCommand"", ""Children"": [ { ""Age"": 0, ""Eta"": 8, ""Gender"": ""Ragel"" }, { ""Age"": 0, ""Eta"": 20, ""Gender"": ""Mara"" } ], ""School"": { ""Title"": ""School for Life"" } } ]";

// 配置JsonSerializerSettings
var serializerSettings = new JsonSerializerSettings
{
    // 这里要和生成原始JSON时的TypeNameHandling保持一致,比如Auto/Objects/All
    TypeNameHandling = TypeNameHandling.Auto,
    SerializationBinder = new CustomTypeBinder()
};

// 直接反序列化为新类型
var result = JsonConvert.DeserializeObject<List<TestClassNew>>(originalJson, serializerSettings);

这种方法的好处是不需要改动原始JSON,所有类型映射逻辑集中在Binder里,后续如果还有其他类型变更,直接修改Binder即可。

方法二:先修改JSON中的$type值再反序列化

如果场景比较简单,也可以先手动修改JSON里的$type字段值,再进行反序列化。推荐用JToken来解析修改,比直接字符串替换更安全(避免误替换到其他字段的内容)。

实现代码:

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

string originalJson = @"[ { ""$type"": ""TestProject.Classes.TestClass, TestProject"", ""Name"": ""TestCommand"", ""Children"": [ { ""Age"": 0, ""Eta"": 8, ""Gender"": ""Ragel"" }, { ""Age"": 0, ""Eta"": 20, ""Gender"": ""Mara"" } ], ""School"": { ""Title"": ""School for Life"" } } ]";

// 解析JSON为JArray
var jArray = JArray.Parse(originalJson);

// 遍历所有对象,替换$type值
foreach (var jObj in jArray.Children<JObject>())
{
    if (jObj.TryGetValue("$type", out JToken typeToken))
    {
        string oldType = typeToken.ToString();
        string newType = oldType.Replace("TestProject.Classes.TestClass", "TestProject.Classes.TestClassNew");
        jObj["$type"] = newType;
    }
}

// 转换为修改后的JSON字符串
string modifiedJson = jArray.ToString();

// 反序列化
var result = JsonConvert.DeserializeObject<List<TestClassNew>>(modifiedJson);

注意事项:

  • 如果用直接字符串替换(比如originalJson.Replace(...)),要确保旧类型字符串不会出现在其他字段值中,否则会导致意外修改。
  • 这种方法适合临时兼容或者JSON结构非常简单的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:01:17