Newtonsoft JSON:TypeNameHandling - $type 用途

Posted

技术标签:

【中文标题】Newtonsoft JSON:TypeNameHandling - $type 用途【英文标题】:Newtonsoft JSON: TypeNameHandling - $type purpose 【发布时间】:2018-04-20 10:50:07 【问题描述】:

在 JSON 数据中生成 $type 值的主要目的(或优势)是什么?它是否以某种方式简化了反序列化?

我通过设置 (de)serializer 的 TypeNameHandling 属性来启用此功能,因为我的意图是进行强大的验证,尤其是在反序列化期间。但是现在我看到反序列化器在反序列化数据时没有问题,即使没有生成 $type 信息。

请问,将 $type 与 Newtonsoft JSON 结合使用的用例是什么?

【问题讨论】:

【参考方案1】:

该设置允许您序列化在其类型定义中具有接口或(抽象)基类的类。

考虑这些类型:

public class MySerializableClass

    public IOther Other get;set;
    public BaseClass Base get;set;


public interface IOther

    public string Foo get;set;


public abstract class BaseClass

    public int MyNumber get;set;

如果你这样做:

JsonConvert.DeserializeObject<MySerializableClass>(json);

json.net 不知道如何创建 IOther 和 Baseclass 的实例,因为它们是抽象的。因此它为您提供了此设置以支持此类基类或接口的序列化,因为它将该属性实例的类型存储在结果 json 的 $type 成员中。

bun 一般建议您不要这样做,因为存储到数据库的 json 中的类型名称或某些内容可能会更改(命名空间更改等),并且在代码更改时反序列化会出现问题。

【讨论】:

所以,如果我是对的,它会指示反序列化器应该使用哪个后代类来实例化数据,好吗?你建议我不要在这种情况下使用 $type 或者在我的 JSON 数据结构中根本没有接口和/或抽象类? 我建议有一个“DTO”(数据传输对象)/POCO(普通旧 clr 对象)类用于存储在磁盘或数据库中的序列化,因为随着时间的推移,如果您的代码随着进化和结构的变化,您的后代类可能不再存在于存储在 json 结构的 $type 成员中的命名空间中。因为我不知道您的确切用例,所以我只想指出这一点,因为我对数据库中的此类数据有过(不好的)经验;)如果您只是临时使用它(在您的应用程序运行时通过网络发送它) ) 使用此功能可能没问题。 感谢您的回答。我有几个专门用于通过网络传输数据的 DTO 类。我在 DTO 设计中有一些接口,并且在任何地方都使用 $type。但现在我看到它使事情变得复杂,所以我想知道它的真正意义。在服务器(javascript)端,验证对我来说也很重要。我还为 DTO 维护 JSON 模式,因此我一直在寻找最简单的方法来管理模式、DTO 和双方的整个验证过程。

以上是关于Newtonsoft JSON:TypeNameHandling - $type 用途的主要内容,如果未能解决你的问题,请参考以下文章

无法将类型“newtonsoft.json.linq.jtoken”隐式转换为 newt“newtonsoft.json.linq.jvalue”

从 JSON 检索项目时获取“无法将 Newtonsoft.Json.Linq.JObject 转换为 Newtonsoft.Json.Linq.JToken”

使用 Newtonsoft.Json 解析 JSON 时出错

Newtonsoft.Json,填充字典失败

Newtonsoft.Json(Json.net) 的使用

Newtonsoft.Json(Json.Net)学习笔记