private Type ResolveImplType(Type objectType, JObject givenJObject, JsonSerializer serializer) { Type targetType = ResolveImplTypeUsingTypeResolverMethod(objectType, givenJObject, serializer); if (targetType != null) { return(targetType); } IEnumerable <Type> knownImplTypes = System.Attribute.GetCustomAttributes(objectType) // Select all custom attribute .Where(ca => ca is KnownTypeAttribute) // filter which are KnownTypeAttribute .Select(kta => (kta as KnownTypeAttribute).Type); // return type of Attribute as type of KnownTypeAttribute var jsonKeysInJsonString = givenJObject.Select <KeyValuePair <string, JToken>, string>(kv => kv.Key).ToList(); var candidateJsonPropertiesUnion = new JsonPropertyCollection(objectType).Select(p => p.PropertyName); foreach (var candidateImplType in knownImplTypes) { var jsonContract = serializer.ContractResolver.ResolveContract(candidateImplType) as JsonObjectContract; candidateJsonPropertiesUnion = candidateJsonPropertiesUnion.Union(jsonContract.Properties.Select(p => p.PropertyName)); } var relevantJsonKeysInJson = jsonKeysInJsonString.Intersect(candidateJsonPropertiesUnion); foreach (var candidateImplType in knownImplTypes) { var jsonContract = serializer.ContractResolver.ResolveContract(candidateImplType) as JsonObjectContract; var jsonPropsInType = jsonContract.Properties; var jsonPropNamesInType = jsonPropsInType.Select(p => p.PropertyName); var missingProperties = relevantJsonKeysInJson.Except(jsonPropNamesInType); if (missingProperties.FirstOrDefault() == null) { return(candidateImplType); } } throw new FabricSerializationException( string.Format("KnownTypeJsonConverter(): None of the known types: {0} has all the properties contained in given json string. Properties in json string: {1}.", string.Join(",", knownImplTypes.Select(t => t.Name)), // comma separated names of known types. string.Join(",", jsonKeysInJsonString))); // comma separated keys in json object }