private JsonMemberMappingCollection CreateMemberMappings(Type objectType) { MemberSerialization memberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType); List<MemberInfo> members = GetSerializableMembers(objectType); if (members == null) throw new JsonSerializationException("Null collection of seralizable members returned."); JsonMemberMappingCollection memberMappings = new JsonMemberMappingCollection(); foreach (MemberInfo member in members) { JsonMemberMapping memberMapping = CreateMemberMapping(memberSerialization, member); memberMappings.AddMapping(memberMapping); } return memberMappings; }
private object PopulateObject(object newObject, JsonReader reader, Type objectType) { JsonMemberMappingCollection memberMappings = GetMemberMappings(objectType); Dictionary <string, bool> requiredMappings = memberMappings.Where(m => m.Required).ToDictionary(m => m.MappingName, m => false); while (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)); } if (reader.TokenType != JsonToken.Null) { SetRequiredMapping(memberName, requiredMappings); } SetObjectMember(reader, newObject, objectType, memberName); break; case JsonToken.EndObject: foreach (KeyValuePair <string, bool> requiredMapping in requiredMappings) { if (!requiredMapping.Value) { throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredMapping.Key)); } } return(newObject); default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); } } throw new JsonSerializationException("Unexpected end when deserializing object."); }
private void SerializeObject(JsonWriter writer, object value) { Type objectType = value.GetType(); #if !SILVERLIGHT && !PocketPC TypeConverter converter = TypeDescriptor.GetConverter(objectType); // use the objectType's TypeConverter if it has one and can convert to a string if (converter != null && !(converter is ComponentConverter) && (converter.GetType() != typeof(TypeConverter) || value is Type)) { if (converter.CanConvertTo(typeof(string))) { writer.WriteValue(converter.ConvertToInvariantString(value)); return; } } #else if (value is Guid || value is Type) { writer.WriteValue(value.ToString()); return; } #endif writer.SerializeStack.Add(value); writer.WriteStartObject(); JsonMemberMappingCollection memberMappings = GetMemberMappings(objectType); foreach (JsonMemberMapping memberMapping in memberMappings) { if (!memberMapping.Ignored && memberMapping.Readable) { WriteMemberInfoProperty(writer, value, memberMapping); } } writer.WriteEndObject(); writer.SerializeStack.RemoveAt(writer.SerializeStack.Count - 1); }
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); }