首页 > 解决方案 > 不知道数据类型时调用 JsonConvert.DeserializeObject?

问题描述

我有一个接收 JOSN 数据的 3rdParty 程序。Json 有两种方式,我使用http://json2csharp.com/创建了两个类来表示两条 JSON 消息

public class Data1
{
    public Content1 content { get; set; }

    public string name { get; set; }

    public string address { get; set; }

    public string age { get; set; }
}


public class Data2
{
    public Content2 content { get; set; }

    public string name { get; set; }

    public string address { get; set; }

    public string age { get; set; }
}

除了 Content1 和 Content2 之外,它们是相同的(我也有它们的类)。

我想像这样反序列化数据:

var object1 = JsonConvert.DeserializeObject<Data1>(message1);
var object2 = JsonConvert.DeserializeObject<Data2>(message2);

但我不知道我会收到什么消息,所以我怎样才能创建一个可以反序列化然后使用的类。

我查看了此示例https://www.jerriepelser.com/blog/deserialize-different-json-object-same-class/并尝试创建具有以下内容的 SuperClass:

[JsonConverter(typeof(SuperData))] 

但我不确定如何实现ReadJson函数。

我是否检查传入的数据并检测内容Content1还是Content2类型?如果是这样,我该怎么做?

那么我如何知道哪些类已被反序列化,以便我可以知道检查不同的内容?

这是json: Data1

{
    "content": {
    "person_id": "1234",
    "timestamp": "2018-10-30 13:09:04.382885",
    "features": "old, cranky"
  },

  "name": "JoeBloggs",
  "address": "address1",    
  "age": 31,    
}

数据2

{
  "content": 
  {
    "detections": 1,

    "detection_boxes": [
      {
        "name": "JoeBloggs",
        "bbox": [
          1988.162842886987,
          -20.466329557695307,
          2662.417876180017,
          846.0808020362452
        ],
        "id": 3610
      }
    ],

    "timestamp": "2018-10-30 13:09:07.171000",
    ]
  },

  "name": "JoeBloggs",
  "address": "address1",    
  "age": 31,    
}

我试过这个:

[JsonConverter(typeof(MyDataConverter))]
public class MegaData
{
    public object content { get; set; }

    public string name { get; set; }

    public string address { get; set; }

    public string age { get; set; }
}

MyDataConverter具有以下内容:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jObject = JObject.Load(reader);
        var content = jObject["message_content"];
        if (content["person_id"] != null)
        {
            return jObject.ToObject<Data1>();
        }
        else
        {
            return jObject.ToObject<Data2>();
        }
    }

然后我尝试按如下方式反序列化它:

var alert = JsonConvert.DeserializeObject<MegaData>(message1); <-- EXCEPTION

**Unable to cast object of type 'Data1' to type 'MegaData'.**

我的 MegaData 类应该是什么样子才能正常工作?

标签: c#json-deserializationjsonconvert

解决方案


JsonConverter因此,您可以创建一个自定义转换器,该转换器源自ReadJson您将执行以下操作:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    var jObject = JObject.Load(reader);
    var content = jObject["content"];
    if (content["person_id"] != null) 
    {
        return jObject.ToObject<Data1>();
    }
    else
    {
        return jObject.ToObject<Data2>();
    }
}

如果您实际上不是在编写 JSON,则可以跳过WriteJson(让它 throw a NotImplementedException) 方法并设置CanWrite为 return false(因此无论如何它都不会被调用)。


推荐阅读