Вызовите JsonConvert.DeserializeObject, если вы не знаете тип данных?
У меня есть программа 3rdParty, из которой я получаю данные JOSN. Json может быть представлен двумя способами, и я создал два класса для представления двух сообщений 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 (у меня есть для них также классы).
Я хочу десериализовать данные следующим образом:
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.
Нужно ли проверять поступающие данные и определять, относится ли контент к типу 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,
}
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, чтобы это работало??
2 ответа
Почему вы не можете иметь один класс с типом и десериализацией до этого типа
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
возвращать false
(так что это никогда не будет называться в любом случае).