private object PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id) { IWrappedDictionary wrappedDictionary = dictionary as IWrappedDictionary; object underlyingDictionary = wrappedDictionary != null ? wrappedDictionary.UnderlyingDictionary : dictionary; if (id != null) AddReference(reader, id, underlyingDictionary); OnDeserializing(reader, contract, underlyingDictionary); int initialDepth = reader.Depth; if (contract.KeyContract == null) contract.KeyContract = GetContractSafe(contract.DictionaryKeyType); if (contract.ItemContract == null) contract.ItemContract = GetContractSafe(contract.DictionaryValueType); JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty); PrimitiveTypeCode keyTypeCode = (contract.KeyContract is JsonPrimitiveContract) ? ((JsonPrimitiveContract)contract.KeyContract).TypeCode : PrimitiveTypeCode.Empty; bool finished = false; do { switch (reader.TokenType) { case JsonToken.PropertyName: object keyValue = reader.Value; if (CheckPropertyName(reader, keyValue.ToString())) continue; try { try { DateParseHandling dateParseHandling; switch (keyTypeCode) { case PrimitiveTypeCode.DateTime: case PrimitiveTypeCode.DateTimeNullable: dateParseHandling = DateParseHandling.DateTime; break; #if !NET20 case PrimitiveTypeCode.DateTimeOffset: case PrimitiveTypeCode.DateTimeOffsetNullable: dateParseHandling = DateParseHandling.DateTimeOffset; break; #endif default: dateParseHandling = DateParseHandling.None; break; } // this is for correctly reading ISO and MS formatted dictionary keys object dt; if (dateParseHandling != DateParseHandling.None && DateTimeUtils.TryParseDateTime(keyValue.ToString(), dateParseHandling, reader.DateTimeZoneHandling, reader.DateFormatString, reader.Culture, out dt)) keyValue = dt; else keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType); } catch (Exception ex) { throw JsonSerializationException.Create(reader, "Could not convert string '{0}' to dictionary key type '{1}'. Create a TypeConverter to convert from the string to the key type object.".FormatWith(CultureInfo.InvariantCulture, reader.Value, contract.DictionaryKeyType), ex); } if (!ReadForType(reader, contract.ItemContract, dictionaryValueConverter != null)) throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object."); object itemValue; if (dictionaryValueConverter != null && dictionaryValueConverter.CanRead) itemValue = DeserializeConvertable(dictionaryValueConverter, reader, contract.DictionaryValueType, null); else itemValue = CreateValueInternal(reader, contract.DictionaryValueType, contract.ItemContract, null, contract, containerProperty, null); dictionary[keyValue] = itemValue; } catch (Exception ex) { if (IsErrorHandled(underlyingDictionary, contract, keyValue, reader as IJsonLineInfo, reader.Path, ex)) HandleError(reader, true, initialDepth); else throw; } break; case JsonToken.Comment: break; case JsonToken.EndObject: finished = true; break; default: throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); } } while (!finished && reader.Read()); if (!finished) ThrowUnexpectedEndException(reader, contract, underlyingDictionary, "Unexpected end when deserializing object."); OnDeserialized(reader, contract, underlyingDictionary); return underlyingDictionary; }
private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { IWrappedDictionary wrappedDictionary = values as IWrappedDictionary; object underlyingDictionary = wrappedDictionary != null ? wrappedDictionary.UnderlyingDictionary : values; OnSerializing(writer, contract, underlyingDictionary); _serializeStack.Add(underlyingDictionary); WriteObjectStart(writer, underlyingDictionary, contract, member, collectionContract, containerProperty); if (contract.ItemContract == null) contract.ItemContract = Serializer._contractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object)); if (contract.KeyContract == null) contract.KeyContract = Serializer._contractResolver.ResolveContract(contract.DictionaryKeyType ?? typeof(object)); int initialDepth = writer.Top; foreach (DictionaryEntry entry in values) { bool escape; string propertyName = GetPropertyName(writer, entry.Key, contract.KeyContract, out escape); propertyName = (contract.PropertyNameResolver != null) ? contract.PropertyNameResolver(propertyName) : propertyName; try { object value = entry.Value; JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value); if (ShouldWriteReference(value, null, valueContract, contract, member)) { writer.WritePropertyName(propertyName, escape); WriteReference(writer, value); } else { if (!CheckForCircularReference(writer, value, null, valueContract, contract, member)) continue; writer.WritePropertyName(propertyName, escape); SerializeValue(writer, value, valueContract, null, contract, member); } } catch (Exception ex) { if (IsErrorHandled(underlyingDictionary, contract, propertyName, null, writer.ContainerPath, ex)) HandleError(writer, initialDepth); else throw; } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, underlyingDictionary); }
private IDictionary CreateNewDictionary(JsonReader reader, JsonDictionaryContract contract, out bool createdFromNonDefaultCreator) { if (contract.IsReadOnlyOrFixedSize) { createdFromNonDefaultCreator = true; return contract.CreateTemporaryDictionary(); } else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) { object dictionary = contract.DefaultCreator(); if (contract.ShouldCreateWrapper) dictionary = contract.CreateWrapper(dictionary); createdFromNonDefaultCreator = false; return (IDictionary)dictionary; } else if (contract.HasParametrizedCreator) { createdFromNonDefaultCreator = true; return contract.CreateTemporaryDictionary(); } else { if (!contract.IsInstantiable) throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); } }