public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return(null); } if (objectType.IsAbstract) { var jo = JObject.Load(reader); Type boType; if (serializer.TypeNameHandling.HasFlag(TypeNameHandling.Objects) && jo.TryGetValue("$type", out var typeToken)) { boType = BusinessObjectSerializationBinder.BusinessObjectAndCOMTypes.SingleOrDefault(t => typeToken.Value <string>().ToUpper().StartsWith(t.FullName.ToUpper())); } else if (!jo.ContainsKey("boTyp")) { throw new ArgumentException( "If deserializing into an abstract BusinessObject the key \"boTyp\" has to be set. But it wasn't."); } else { #pragma warning disable CS0618 // Type or member is obsolete boType = BoMapper.GetTypeForBoName(jo["boTyp"] .Value <string>()); // ToDo: catch exception if boTyp is not set and throw exception with descriptive error message #pragma warning restore CS0618 // Type or member is obsolete } if (boType == null) { foreach (var assembley in AppDomain.CurrentDomain.GetAssemblies()) { try { boType = assembley.GetTypes().FirstOrDefault(x => string.Equals(x.Name, jo["boTyp"].Value <string>(), StringComparison.CurrentCultureIgnoreCase)); } catch (ReflectionTypeLoadException) { continue; } if (boType != null) { break; } } if (boType == null) { throw new NotImplementedException( $"The type '{jo["boTyp"].Value<string>()}' does not exist in the BO4E standard."); } } var deserializationMethod = serializer.GetType() // https://stackoverflow.com/a/5218492/10009545 .GetMethods() .Where(m => m.Name == nameof(serializer.Deserialize)) .Select(m => new { Method = m, Params = m.GetParameters(), Args = m.GetGenericArguments() }) .Where(x => x.Params.Length == 1 && x.Args.Length == 1) .Select(x => x.Method) .First() .GetGenericMethodDefinition() .MakeGenericMethod(boType); try { return(deserializationMethod.Invoke(serializer, new object[] { jo.CreateReader() })); } catch (TargetInvocationException tie) when(tie.InnerException != null) { throw tie.InnerException; // to hide the reflection to the outside. } } serializer.ContractResolver.ResolveContract(objectType).Converter = null; return(serializer.Deserialize(JObject.Load(reader).CreateReader(), objectType)); }