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
相关产品推荐
相关产品推荐

