public class TestConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//Type valueType = value.GetType();
//if (valueType.IsArray)
//{
// var jArray = new JArray();
// foreach (var item in (IEnumerable)value)
// jArray.Add(JToken.FromObject(item, serializer));
// jArray.WriteTo(writer);
//}
//else
//{
// JProperty typeHintProperty = TypeHintPropertyForType(valueType);
// var jObj = new JObject();
// if (typeHintProperty != null)
// jObj.Add(typeHintProperty);
// foreach (PropertyInfo property in valueType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
// {
// if (property.CanRead)
// {
// object propertyValue = property.GetValue(value, null);
// if (propertyValue != null)
// jObj.Add(property.Name, JToken.FromObject(propertyValue, serializer));
// }
// }
// jObj.WriteTo(writer);
//}
}
public override bool CanWrite => false;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
// Load JObject from stream
JObject jObject = JObject.Load(reader);
Type targetType;
JToken typeStr;
//JToken varl;
if (!jObject.TryGetValue("_t", out typeStr))
{
targetType = objectType;
}
else
{
var scrName = typeStr.ToString();
if (scrName.Contains("."))
{
scrName = scrName.Substring(scrName.LastIndexOf(".", StringComparison.Ordinal)+);
}
targetType = PropertyHintTypeForStr(scrName);
}
// Displaying output.
var target = Activator.CreateInstance(targetType);
serializer.Populate(jObject.CreateReader(), target);
return target;
}
public override bool CanConvert(Type objectType)
{
return typeof(BaseTest).IsAssignableFrom(objectType);
}
//public override bool CanRead=>false;
private Type PropertyHintTypeForStr(string typeStr)
{
Type result;
switch (typeStr)
{
case nameof(BaseTest):
result = typeof(BaseTest);break;
case nameof(TestA):
result = typeof(TestA); break;
case nameof(TestB):
result = typeof(TestB); break;
case nameof(TestC):
result = typeof(TestC); break;
case nameof(TestD):
result = typeof(TestD); break;
case nameof(TestE):
result = typeof(TestE); break;
case nameof(TestX):
result = typeof(TestX); break;
default:
result = typeof(BaseTest); break;
}
return result;
}
}