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

Newtonsoft.Json 8.0.0.0的TypeNameAssemblyFormatHandling等效项查询

解决Newtonsoft.Json 8.0.0.0中移除类型序列化版本号的问题

我正好在旧项目里折腾过Newtonsoft.Json 8.x的类型格式化问题,针对你遇到的「文档方案无效、程序集版本号依然存在」的情况,这里有几个经过验证的可行方案:

方案一:自定义SerializationBinder完全控制类型名称

这是最可靠的方式,因为8.0版本的TypeNameAssemblyFormatHandling可能无法完全移除版本号(比如Simple模式依然会保留程序集名称+版本的部分信息),而自定义绑定器可以彻底接管序列化和反序列化的类型命名逻辑。

实现自定义绑定器

using System;
using System.Reflection;
using Newtonsoft.Json.Serialization;

public class VersionStrippingBinder : SerializationBinder
{
    // 反序列化时:忽略传入的版本号,找到正确的类型
    public override Type BindToType(string assemblyName, string typeName)
    {
        // 优先从当前程序集查找
        var currentAssembly = Assembly.GetExecutingAssembly();
        var targetType = currentAssembly.GetType(typeName);
        
        // 如果当前程序集没有,遍历所有已加载的程序集查找
        if (targetType == null)
        {
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                targetType = assembly.GetType(typeName);
                if (targetType != null) break;
            }
        }

        if (targetType == null)
            throw new TypeLoadException($"无法加载类型:{typeName}");
        
        return targetType;
    }

    // 序列化时:只输出类型全名,不附带任何程序集版本信息
    public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
    {
        typeName = serializedType.FullName;
        // 如果需要保留程序集名称但去掉版本,可以改成下面这行
        // assemblyName = serializedType.Assembly.GetName().Name;
        assemblyName = null;
    }
}

应用到序列化设置

var jsonSettings = new JsonSerializerSettings
{
    // 根据你的需求选择TypeNameHandling:Auto/Objects/All等
    TypeNameHandling = TypeNameHandling.Auto,
    SerializationBinder = new VersionStrippingBinder()
};

// 序列化示例
string serializedJson = JsonConvert.SerializeObject(yourGameObject, jsonSettings);

// 反序列化示例
var deserializedObj = JsonConvert.DeserializeObject<YourGameType>(serializedJson, jsonSettings);

方案二:调整TypeNameAssemblyFormatHandling结合自定义处理(仅部分场景有效)

如果你之前尝试的是TypeNameAssemblyFormatHandling.Simple,它在8.0版本中确实只会移除文化和公钥信息,但版本号依然会保留。如果只需要移除版本号,可以结合字符串替换临时解决,但这种方式非常脆弱:

var settings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto,
    TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple
};

// 序列化后手动替换版本号(不推荐,容易出错)
string json = JsonConvert.SerializeObject(obj, settings);
json = json.Replace(", Version=8.0.0.0, Culture=neutral, PublicKeyToken=null", "");

⚠️ 注意:这种硬编码替换的方式仅适用于固定版本的场景,一旦程序集版本或类型信息变化就会失效,优先推荐方案一。

关键注意事项

  • 如果你的类型来自Rust服务器的第三方程序集,在BindToType方法中需要确保能正确找到对应程序集,可能需要根据程序集名称(不带版本)去加载或查找。
  • 测试时务必覆盖序列化和反序列化的全流程,避免出现类型无法加载的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:18:04