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”