I want to deserialize json messages via json.net, and I have the following json object (which might not be optimal!!!)
{
"deviceId":"XXXX",
"messages":
[
{
"type":"messageType1",
"version":1,
"content":
{
"propertyA":"ValueA"
}
},
{
"type":"messageType2",
"version":1,
"content":
{
"propertyB":"ValueB"
}
}
]
}
Would it be possible to use a "CustomCreationConverter" for that?
I was hoping to use "type" for detection of correct class...
BR Martin
------------ UPDATE -----------------
I have now implemented the following solution, and would appreciate any feedback.
public class MessageType1
{
public string PropertyA{ get; set; }
}
public class MessageType2
{
public string PropertyB{ get; set; }
}
public abstract class MessageEntity
{
[JsonConverter(typeof(ContentConverter))]
abstract public string Type { get; set; }
abstract public int Version { get; set; }
}
public class Type1MessageEntity : MessageEntity
{
override public string Type { get; set; }
override public int Version { get; set; }
public Type1Message Content { get; set; }
}
public class Type2MessageEntity : MessageEntity
{
override public string Type { get; set; }
override public int Version { get; set; }
public Type2Message Content { get; set; }
}
public sealed class ContentConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(MessageEntity).IsAssignableFrom(objectType);
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
// Try to parse basic information from object
string type = (string)jObject["type"].ToObject<string>();
int version = (int)jObject["version"].ToObject<int>();
JToken contentValue;
try
{
type = (string)jObject["type"].ToObject<string>();
version = (int)jObject["version"].ToObject<int>();
contentValue = jObject["content"];
}
catch
{
throw new JsonSerializationException($"Incorrect format");
}
// Try to parse content
MessageEntity messageEntity = null;
try
{
switch (type)
{
case "messageType1":
{
messageEntity = new Type1MessageEntity();
messageEntity.Type = type;
messageEntity.Version = version;
(messageEntity as Type1MessageEntity).Content = contentValue.ToObject<Type1Message>(serializer);
break;
}
case "messageType2":
{
messageEntity = new Type2MessageEntity();
messageEntity.Type = type;
messageEntity.Version = version;
(messageEntity as Type2MessageEntity).Content = contentValue.ToObject<Type2Message>(serializer);
break;
}
default:
{
throw new JsonSerializationException($"Unsupported type: '{type}'");
}
}
}
catch
{
throw new JsonSerializationException($"Incorrect content format");
}
return messageEntity;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}