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;
    

ISerializationBinderJson.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)的方法,这意味着无法定义类型名称。

那么,在 Unity 中如何解决序列化问题 - 仅使用类名? (这里只设置TypeNameHandling = TypeNameHandling.Objects,是没有办法的) 为什么每个人都声称他们是相同的,而事实显然并非如此? (甚至下面的 Json.net 的 *** 标记也是如此。) 这种差异是否与 Unity 使用 Mono 的事实有关?

谢谢。

【问题讨论】:

Json.NET 与 Newtonsoft.Json 是一回事。您必须尝试对不同版本的 Json.NET 使用相同的代码。在Json.NET 10.0.1Newtonsoft Added ISerializationBinderObsoleted 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 一起使用?

如何使用 Linq 获取列中每个不同值的计数

使用Newtonsoft.Json.dll(JSON.NET)动态解析JSON.net 的json的序列化与反序列化

如何使用与 NewtonSoft (JSON.Net) 组件中的 JSON 匹配的 Swift 类从/向 JSON 读取/写入对象数组?

JSON.NET与LINQ序列化示例教程