Json.NET 与 Newtonsoft.Json SerializationBinder 不同
Posted
技术标签:
【中文标题】Json.NET 与 Newtonsoft.Json SerializationBinder 不同【英文标题】:Json.NET vs Newtonsoft.Json SerializationBinder is different 【发布时间】:2019-02-17 20:21:16 【问题描述】:我知道这个话题有很多类似的问题,但我在这里没有找到答案。
我已经在 Unity 中下载了 Json.net
,在另一个项目中下载了 Newtonsoft.json
作为 NuGet 包。 Newtonsoft.json
正在工作,我尝试在 Unity 项目中使用此工作解决方案。
我需要使用ISerializationBinder
来转换抽象类层次结构,并且我想仅序列化/反序列化类名,而不是它们的完整程序集名称. (原因是 C# 代码应该与不同的程序通信。)
我使用具有以下序列化类的解决方案(从在线官方示例复制):
public class KnownTypesBinder : ISerializationBinder
public IList<Type> KnownTypes get; set;
public Type BindToType(string assemblyName, string typeName)
return KnownTypes.SingleOrDefault(t => t.Name == typeName);
public void BindToName(Type serializedType, out string assemblyName, out string typeName)
assemblyName = null;
typeName = serializedType.Name;
ISerializationBinder
在Json.net
中不存在。 JsonSerializerSettings
明显不同:
Newtonsoft.json
:
public class JsonSerializerSettings
public ISerializationBinder SerializationBinder get; set;
Json.net
:
public class JsonSerializerSettings
public SerializationBinder Binder get; set;
System.Runtime.Serialization.SerializationBinder
(不是从ISerializationBinder
派生的)没有名为public void BindToName(Type serializedType, out string assemblyName, out string typeName)
的方法,这意味着无法定义类型名称。
TypeNameHandling = TypeNameHandling.Objects,
是没有办法的)
为什么每个人都声称他们是相同的,而事实显然并非如此? (甚至下面的 Json.net
的 *** 标记也是如此。)
这种差异是否与 Unity 使用 Mono 的事实有关?
谢谢。
【问题讨论】:
Json.NET 与 Newtonsoft.Json 是一回事。您必须尝试对不同版本的 Json.NET 使用相同的代码。在Json.NET 10.0.1Newtonsoft Added ISerializationBinder 和Obsoleted SerializationBinder 中,如果您尝试将针对 10.0.1 或更高版本编写的代码反向移植到早期版本,您将遇到兼容性问题。 1) 是的——但我相信 Newtonsoft 没有针对 Unity3d 的 Json.NET 官方版本。相反,有基于特定版本的 Json.NET 的第 3 方构建,所以也许您正在使用一个? 2)SerializationBinder.BindToName()
最初是在 .Net 4.0 中引入的。如果您的 Unity 使用的是早期版本,您将不会拥有它。
3) 顺便说一下,.Net 版本之间 SerializationBinder
的不一致是 Newtonsoft 将其替换为 ISerializationBinder
的原因。
早期版本的Json.NET使用条件编译来选择是否调用BindToName
,如github.com/JamesNK/Newtonsoft.Json/blob/8.0.3/Src/…所示。所以这真的取决于你的 Unity3d 特定的 Json.NET DLL 是如何编译的。
真正的问题是您的 Json.NET 版本早于 10.0 版,并且编译为 .Net 4.0 版之前的版本。如果您可以修改其中任何一种情况,您就可以了。 1() 如果您的 Json.NET 是 10.0.1 或更高版本,您可以使用 ISerializationBinder.BindToName
,它甚至可以在 .Net 3.5 上使用。 2) 或者,如果您可以获得针对 .net 4.0 或更高版本的 Json.NET 8.0.3 构建,您可以使用SerializatinBinder.BindToName
。无论哪种方式,您的问题都可以解决。那么,您能找到更新的 Json.NET 版本以实现统一吗?还是自己造一个?
【参考方案1】:
这是一个版本问题。您所指的 JSON .NET for Unity
就像 Json.NET
使用(如 cmets 中所述)Newtonsoft.Json 8.0.3。
如果您想使用 Newtonsoft.Json 的新功能,我建议您使用不同的解决方案。目前为 Unity 制作的最新版 Newtonsoft.Json 分支在这里:https://github.com/jilleJr/Newtonsoft.Json-for-Unity#readme,在撰写本文时位于 Newtonsoft.Json 12.0.3。
jilleJr/Newtonsoft.Json-for-Unity 也通过内置的 Unity 包管理器进行部署,因此用户也可以更轻松地保持最新状态。
【讨论】:
以上是关于Json.NET 与 Newtonsoft.Json SerializationBinder 不同的主要内容,如果未能解决你的问题,请参考以下文章
Newtonsoft JSON.NET 与 Json Web 服务的兼容性
如何将 HTML 表转换为 JSON 并将 JSON 与 JSON.NET 一起使用?
使用Newtonsoft.Json.dll(JSON.NET)动态解析JSON.net 的json的序列化与反序列化
如何使用与 NewtonSoft (JSON.Net) 组件中的 JSON 匹配的 Swift 类从/向 JSON 读取/写入对象数组?