不知道数据类型时调用JsonConvert.DeserializeObject?

Call JsonConvert.DeserializeObject when you dont know the data type?

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

的消息
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 之外它们是相同的(我也有 class它们)。

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

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

但我不知道我会收到什么消息,所以我如何创建一个 class 我可以反序列化然后使用的消息。

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

[JsonConverter(typeof(SuperData))] 

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

我是否检查传入的数据并检测 content 的类型是 Content1 还是 Content2?如果可以,我该怎么做?

然后我怎么知道 class 已经被反序列化,然后我可以知道检查不同的内容?

这是 json: 数据1

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

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

Data2

{
  "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 class 应该是什么样子才能工作?

为什么你不能有一个 class 类型和反序列化到

public class DetectionBox
{
    public string name { get; set; }
    public List<double> bbox { get; set; }
    public int id { get; set; }
}

public class Content
{
    public int detections { get; set; }
    public List<DetectionBox> detection_boxes { get; set; }
    public string timestamp { get; set; }
    public string person_id { get; set; }
    public string features { get; set; }
}

public class Data
{
    public Content content { get; set; }
    public string name { get; set; }
    public string address { get; set; }
    public int age { get; set; }
}


Data data = JsonConvert.DeserializeObject<Data>(json);

因此您可以创建一个派生自 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(让它抛出 NotImplementedException)方法并将 CanWrite 设置为 return false(所以它永远不会被调用)。