不知道数据类型时调用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
(所以它永远不会被调用)。
我有一个从中接收 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
(所以它永远不会被调用)。