如何处理反序列化变化的 JSON 数据?

Posted

技术标签:

【中文标题】如何处理反序列化变化的 JSON 数据?【英文标题】:How to handle deserializing JSON data that varies? 【发布时间】:2016-02-13 05:02:41 【问题描述】:

问题背景:

我正在调用亚马逊产品广告 API,并从他们的服务接收 JSON 格式的产品列表。

问题:

遗憾的是,JSON 响应因提供给 API 的参数而异。例如:搜索“体育用品”对“手表”的响应略有不同。

下面给出了一个非常简单的差异示例:

从 API 接收到的体育用品 JSON:


    "Item": 
        "ID": "145",
        "Title": "Football",
        "ImageUrl": "http://amazon.com/football.jpg",
        "Shipping": "UK",
        "ListPrice": "7.99"
    

观察从 API 接收到的 JSON:


    "Item": 
        "ID": "567",
        "Title": "RolexWatch",
        "ImageUrl": "http://amazon.com/RolexWatch.jpg",
        "Shipping": "UK",
        "ListPrice": "£7000.00",
        "SalePrice": "£6500.00"   <------------- extra item in Watches JSON
    

我目前正在使用 NewtonSoft 将两个响应反序列化为两个不同的 C# 模型,即:

 public class SportingGoods
    
      public string ID set;get;
      public string Title set;get;
      public string ImagesUrl set;get;
      public string Shippingset;get;
      public string ListPriceset;get;
    

public class Watches
    
      public string ID set;get;
      public string Title set;get;
      public string ImagesUrl set;get;
      public string Shippingset;get;
      public string ListPriceset;get;
      public string SalePriceset;get;
    

我发现来自 Amazon API 的 JSON 响应还有其他变化。 当 JSON 数据变化如此之大时,如何正确处理这种反序列化?当我不能 100% 确定 JSON 会是什么样子时,我无法继续创建不同的模型。

【问题讨论】:

【参考方案1】:

您可以使用 JObject.Parse() 在 C# 中使用动态类型,您只需要小心使用它,因为字段可能存在也可能不存在。

dynamic foo = JObject.Parse(jsonText);
string bar = foo.Bar; // bar = "something"

【讨论】:

【参考方案2】:

在您给出的示例中,两种模型之间的唯一区别似乎是一种具有SalePrice 字段,而另一种则没有。否则,它们是相同的。这种情况其实很常见,处理起来也没什么大不了的。

默认情况下,JSON.Net 会跳过 JSON 中没有对应字段的类成员,反之亦然。因此,您可以简单地定义一个 Product 模型,其中包含您感兴趣的所有可能的产品字段,并将其用于这两种情况。对于体育用品,SalePrice 将简单地为空。如果稍后在 JSON 中出现了一个您并不真正关心的额外字段,没问题——它将被忽略。

public class Product

    public string ID  get; set; 
    public string Title  get; set; 
    public string ImagesUrl  get; set; 
    public string Shipping  get; set; 
    public string ListPrice  get; set; 
    public string SalePrice  get; set; 

现在,如果您的 JSON 变化更大,例如,如果一个字段有时是一个字符串,有时是一个字符串列表,那么您必须开始寻找其他方法。一种可能性是编写自定义JsonConverter 来处理差异。另一种可能性是反序列化为JObjectdynamic,而不是使用强类型类。

【讨论】:

以上是关于如何处理反序列化变化的 JSON 数据?的主要内容,如果未能解决你的问题,请参考以下文章

Jackson - 如何处理(反序列化)嵌套的 JSON?

spring boot中各种数据不匹配如何处理jackson反序列化错误

Java Jackson json 到对象反序列化。如何处理 OWASP 不安全的反序列化?

反序列化 JSON 日期无时区

C#动态实体集的反序列化(动态JSON反序列化)

如何反序列化不同类型的 JSON 数组?