Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
/// <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.");
}
@StephenCleary

This comment has been minimized.

Copy link
Owner Author

StephenCleary commented Sep 6, 2017

Untested.

When JSON.NET vNext is released, this should change its base class to JsonConverter<T> and pass T existingValue, bool hasExistingValue to GetType.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.