private void SetObjectMember(JsonReader reader, object target, Type targetType, string memberName) { JsonMemberMappingCollection memberMappings = GetMemberMappings(targetType); JsonMemberMapping memberMapping; // attempt exact case match first // then try match ignoring case if (memberMappings.TryGetClosestMatchMapping(memberName, out memberMapping)) { SetMappingValue(memberMapping, reader, target); } else { if (_missingMemberHandling == MissingMemberHandling.Error) { throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, targetType.Name)); } reader.Skip(); } }
private object CreateObjectFromNonDefaultConstructor(Type objectType, JsonReader reader) { // object should have a single constructor ConstructorInfo c = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).SingleOrDefault(); if (c == null) { throw new JsonSerializationException("Could not find a public constructor for type {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); } // create a dictionary to put retrieved values into JsonMemberMappingCollection memberMappings = GetMemberMappings(objectType); IDictionary <JsonMemberMapping, object> mappingValues = memberMappings.ToDictionary(kv => kv, kv => (object)null); bool exit = false; while (!exit && reader.Read()) { switch (reader.TokenType) { case JsonToken.PropertyName: string memberName = reader.Value.ToString(); if (!reader.Read()) { throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); } JsonMemberMapping memberMapping; // attempt exact case match first // then try match ignoring case if (memberMappings.TryGetClosestMatchMapping(memberName, out memberMapping)) { if (!memberMapping.Ignored) { Type memberType = ReflectionUtils.GetMemberUnderlyingType(memberMapping.Member); mappingValues[memberMapping] = CreateObject(reader, memberType, null, memberMapping.MemberConverter); } } else { if (_missingMemberHandling == MissingMemberHandling.Error) { throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name)); } reader.Skip(); } break; case JsonToken.EndObject: exit = true; break; default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); } } IDictionary <ParameterInfo, object> constructorParameters = c.GetParameters().ToDictionary(p => p, p => (object)null); IDictionary <JsonMemberMapping, object> remainingMappingValues = new Dictionary <JsonMemberMapping, object>(); foreach (KeyValuePair <JsonMemberMapping, object> mappingValue in mappingValues) { ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, mappingValue.Key.MappingName).Key; if (matchingConstructorParameter != null) { constructorParameters[matchingConstructorParameter] = mappingValue.Value; } else { remainingMappingValues.Add(mappingValue); } } object createdObject = ReflectionUtils.CreateInstance(objectType, constructorParameters.Values.ToArray()); // go through unused values and set the newly created object's properties foreach (KeyValuePair <JsonMemberMapping, object> remainingMappingValue in remainingMappingValues) { if (ShouldSetMappingValue(remainingMappingValue.Key, remainingMappingValue.Value)) { ReflectionUtils.SetMemberValue(remainingMappingValue.Key.Member, createdObject, remainingMappingValue.Value); } } return(createdObject); }