提问者:小点点

JSON.net 合约解析器与 Json转换器


我已经和 JSON.net 合作了一段时间。我已经编写了自定义转换器和自定义合约解析器(通常来自 S.O. 和 Newtonsoft 网站上的修改示例),它们工作正常。

挑战在于,除了示例之外,我几乎没有看到关于何时应该使用一个或另一个(或两个)进行处理的解释。通过我自己的经验,我基本上已经确定合同解决器更简单,所以如果我能用它们做我需要的事情,我就会走这条路;否则,我使用自定义 JsonConverters。但是,我进一步知道两者有时一起使用,因此概念变得更加不透明。

问题:

  1. 是否有一个来源可以区分何时使用一个用户与另一个用户?我发现Newtonsoft文档不清楚两者是如何区分的,或者何时使用其中一个。
  2. 两者之间的排序管道是什么?

共1个答案

匿名用户

好问题。我还没有看到一个明确的文档说什么时候你应该更愿意编写一个自定义的ContractResolver或一个自定义的JsonConverter来解决特定类型的问题。他们确实做不同的事情,但每个人可以解决什么样的问题之间存在一些重叠。在回答StackOverflow上的问题时,我已经写了相当多的,所以随着时间的推移,情况对我来说变得更加清晰。以下是我对它的看法。

协定解析器始终由 Json.Net 使用,并在广泛的级别上控制序列化/反序列化行为。如果设置中未提供自定义解析程序,则使用 DefaultContract 解析程序。解析程序负责确定:

  • 每种类型有什么协定(即它是原语、数组/列表、字典、动态、JObject、普通旧对象等);
  • 类型上有哪些属性(如果有的话)以及它们的名称、类型和可访问性是什么;
  • 应用了哪些属性(例如 [JsonProperty]、[JsonIgnore]、[JsonConverter]),以及
  • 这些属性应如何影响每个属性(或类)的(反)序列化。

一般来说,如果要跨各种类自定义序列化或反序列化的某些方面,则可能需要使用 ContractResolver 来执行此操作。下面是您可以使用合同解析程序自定义的一些内容示例:

  • 更改用于类型的协定
    • 将所有字典序列化为键/值对数组
    • 将列表项序列化为常规对象而不是字符串
    • 对所有属性名称使用驼峰大小写
    • 骆驼大小写除字典以外的所有属性名称
    • 在没有属性的类上全局使用 JsonConverter
    • 将属性重新映射到运行时定义的不同名称
    • 允许使用非公共资源库反序列化到公共属性
    • (可选)在运行时关闭 JsonIgnore 属性
    • 使标记为必需的属性(对于 SOAP)对于 JSON 不需要
    • 忽略所有类中的只读属性
    • 跳过序列化引发异常的属性
    • 加密任何类中特别标记的字符串属性
    • 在反序列化期间有选择地转义字符串中的 HTML

    ContractResolver 相比,JsonConverter 的重点更窄:它实际上旨在处理单个类型或相关类型的一小部分子集的序列化或反序列化。此外,它的工作级别低于解析器。当转换器负责某个类型时,它可以完全控制如何读取或写入该类型的 JSON:它直接使用 JsonReader 和 JsonWriter 类来完成它的工作。换句话说,它可以更改该类型的 JSON 形状。同时,转换器是与“大图”分离,并且无法访问上下文信息,例如正在(反)序列化的对象的父级或与之一起使用的属性属性。以下是您可以使用 JsonConverter 解决的一些问题示例:

    • 处理反序列化时的对象实例化问题
      • 反序列化为接口,使用 JSON 中的信息来决定要实例化的具体类
      • 反序列化有时是单个对象,有时是对象数组的 JSON
      • 反序列化可以是数组或嵌套数组的 JSON
      • 从混合类型数组反序列化时跳过不需要的项目
      • 反序列化为缺少默认构造函数的对象
      • 将十进制值序列化为本地化字符串
      • 转换十进制。最小值到空字符串并返回(用于旧系统)
      • 使用多种不同格式序列化日期
      • 反序列化日期时忽略 UTC 偏移
      • 在序列化类型时 Json.Net 调用 ToString()
      • 将混合值的嵌套数组反序列化为项列表
      • 反序列化具有不同名称的对象数组
      • 序列化
      • /反序列化具有复杂键的自定义字典
      • 将自定义 IEnumerable 集合序列化为字典
      • 将嵌套的 JSON 结构平展为更简单的对象结构
      • 将简单的对象结构扩展为更复杂的 JSON 结构
      • 仅将对象列表序列化为 ID 列表
      • 反序列化对象的 JSON 列表将 GUID 链接到 GUID 列表
      • 序列化 System.Net.IPAddress 引发异常
      • 反序列化 Microsoft.Xna.Framework.Rectangle 时出现问题