public override object?ReadJson(JsonReader reader, Type objectType, object?existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return(null); } var jo = JObject.Load(reader); var designatingProperty = jo.GetValue(TypeDesignatingPropertyName); if (designatingProperty == null) { throw new Exception("Null value returned for the Type Designator"); } var derivedType = designatingProperty.ToObject <string>() ?? string.Empty; if (!DerivedTypeMappings.ContainsKey(derivedType)) { throw new Exception($"Unable to determine type to deserialize. {TypeDesignatingPropertyName} `{derivedType}` does not map to a known type"); } var type = DerivedTypeMappings[derivedType]; var ctor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).Single(); var args = ctor.GetParameters() .Select(p => jo.GetValue(char.ToUpper(p.Name ![0]) + p.Name.Substring(1))
protected override TypeInfo GetTypeInfoFromDerivedType(string derivedType) { var type = typeof(TDiscriminator); if (type.IsEnum) { var enumType = (TDiscriminator)Enum.Parse(type, derivedType); if (!DerivedTypeMappings.ContainsKey(enumType)) { throw new Exception($"Unable to determine type to deserialize. {TypeDesignatingPropertyName} `{enumType}` does not map to a known type"); } return(DerivedTypeMappings[enumType].GetTypeInfo()); } if (type == typeof(string)) { var mappings = (Dictionary <string, Type>)DerivedTypeMappings; if (!mappings.ContainsKey(derivedType)) { throw new Exception($"Unable to determine type to deserialize. {TypeDesignatingPropertyName} `{derivedType}` does not map to a known type"); } return(mappings[derivedType].GetTypeInfo()); } throw new Exception("Unable to determine type to deserialize, override GetTypeInfoFromDerivedType to map the derivedType"); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return(null); } var jo = JObject.Load(reader); var contractResolver = serializer.ContractResolver; var designatingProperty = jo.GetValue(getMappedPropertyName(contractResolver, TypeDesignatingPropertyName)); Type type; if (designatingProperty == null) { if (DefaultType == null) { throw new Exception($"Unable to determine type to deserialize. Missing property `{TypeDesignatingPropertyName}`"); } type = DefaultType; } else { var derivedType = designatingProperty.ToObject <string>(); var enumType = (TEnumType)Enum.Parse(typeof(TEnumType), derivedType); if (!DerivedTypeMappings.ContainsKey(enumType)) { throw new Exception($"Unable to determine type to deserialize. {TypeDesignatingPropertyName} `{enumType}` does not map to a known type"); } type = DerivedTypeMappings[enumType]; } var ctor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).Single(); var args = ctor.GetParameters().Select(p => jo.GetValue(char.ToUpper(p.Name[0]) + p.Name.Substring(1)) .ToObject(p.ParameterType, serializer)).ToArray(); var instance = ctor.Invoke(args); foreach (var prop in type .GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty) .Where(p => p.CanWrite)) { var propertyName = getMappedPropertyName(contractResolver, prop.Name); var val = jo.GetValue(propertyName); if (val != null) { prop.SetValue(instance, val.ToObject(prop.PropertyType, serializer), null); } } return(instance); }
protected override TypeInfo GetTypeInfoFromDerivedType(string derivedType) { var enumType = (TDiscriminator)Enum.Parse(typeof(TDiscriminator), derivedType); if (!DerivedTypeMappings.ContainsKey(enumType)) { throw new Exception( $"Unable to determine type to deserialize. {TypeDesignatingPropertyName} `{enumType}` does not map to a known type"); } var typeInfo = DerivedTypeMappings[enumType].GetTypeInfo(); return(typeInfo); }