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

时间:2018-10-30 19:45:11

标签: c# json-deserialization jsonconvert

我有一个3rdParty程序,可以从中接收JOSN数据。 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/,并试图创建一个具有以下内容的超类:

[JsonConverter(typeof(SuperData))] 

但是我不确定如何实现 ReadJson 功能。

我是否检查输入的数据并检测 content Content1 还是 Content2 ?如果是这样,我该怎么做?

然后我如何知道已反序列化了哪个类,以便随后知道检查不同的内容?

这是json: 数据1

{
    "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类应如何工作?

2 个答案:

答案 0 :(得分:1)

为什么不能有一个既有类型又有反序列化的类

{{1}}

答案 1 :(得分:1)

因此,您可以创建一个从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设置为返回false(因此无论如何都不会被调用。)