Created
September 6, 2017 01:16
-
-
Save StephenCleary/f10245ab46ca269fe62e64f401ed4c9e to your computer and use it in GitHub Desktop.
A JsonConverter that determines the type of the deserialized object by its JSON representation. Combination of several approaches including CustomCreatorConverter and https://stackoverflow.com/questions/22537233/json-net-how-to-deserialize-interface-property-based-on-parent-holder-object/22539730#22539730
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Creates a custom object based on the json values. | |
/// </summary> | |
/// <typeparam name="T">The object type to convert.</typeparam> | |
public abstract class JsonCreationConverter<T> : JsonConverter | |
{ | |
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) | |
{ | |
if (reader.TokenType == JsonToken.Null) | |
return null; | |
var jobject = JObject.Load(reader); | |
var type = GetType(jobject, objectType, existingValue); | |
if (type == null) | |
throw new JsonSerializationException("Could not determine object type."); | |
return jobject.ToObject(type, serializer); | |
} | |
/// <summary> | |
/// Determines the type of object being deserialized. | |
/// </summary> | |
/// <param name="json">The JSON object.</param> | |
/// <param name="objectType">Type that JSON.NET thinks the object should be. This parameter is usually ignored.</param> | |
/// <param name="existingValue">The existing value of the object being read. This parameter is usually ignored.</param> | |
public abstract Type GetType(JObject json, Type objectType, object existingValue); | |
public override bool CanConvert(Type objectType) => typeof(T).IsAssignableFrom(objectType); | |
public override bool CanWrite => false; | |
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotSupportedException("JsonCreationConverter should only be used while deserializing."); | |
} |
typeof(T).IsAssignableFrom(objectType) - I get objectType as my base class form jsonString event if in json string there is conrete class.
For example:
abstract class ClassBase
class ClassA : ClassBase
and I have in json string information about type: ClassA but while deserializon CanConvert(Type objectType) the objectType name is ClassBase and then typeof(T).IsAssignableFrom(objectType) is alsways false.
Does sb know why? How to get in objectType the conrete class (here ClassA?)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Untested.
When JSON.NET vNext is released, this should change its base class to
JsonConverter<T>
and passT existingValue, bool hasExistingValue
toGetType
.