public void Serialize(JsonWriter jsonWriter, object value, Type objectType) { if (jsonWriter == null) throw new ArgumentNullException("jsonWriter"); if (objectType != null) _rootContract = Serializer._contractResolver.ResolveContract(objectType); SerializeValue(jsonWriter, value, GetContractSafe(value), null, null, null); }
private bool ShouldWriteReference(object value, JsonProperty property, JsonContract contract) { if (value == null) return false; if (contract is JsonPrimitiveContract) return false; bool? isReference = null; // value could be coming from a dictionary or array and not have a property if (property != null) isReference = property.IsReference; if (isReference == null) isReference = contract.IsReference; if (isReference == null) { if (contract is JsonArrayContract) isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays); else isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects); } if (!isReference.Value) return false; return Serializer.ReferenceResolver.IsReferenced(this, value); }
private JsonArrayContract EnsureArrayContract(Type objectType, JsonContract contract) { if (contract == null) throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); JsonArrayContract arrayContract = contract as JsonArrayContract; if (arrayContract == null) throw new JsonSerializationException("Cannot deserialize JSON array into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); return arrayContract; }
private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter) { JsonConverter converter = null; if (memberConverter != null) { // member attribute converter converter = memberConverter; } else if (contract != null) { JsonConverter matchingConverter; if (contract.Converter != null) // class attribute converter converter = contract.Converter; else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null) // passed in converters converter = matchingConverter; else if (contract.InternalConverter != null) // internally specified converter converter = contract.InternalConverter; } return converter; }
private object CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract) { JsonConverter converter = GetConverter(contract, null); if (converter != null && converter.CanRead) return converter.ReadJson(reader, objectType, null, GetInternalSerializer()); return CreateValueInternal(reader, objectType, contract, null, null); }
private string GetPropertyName(JsonWriter writer, object name, JsonContract contract, out bool escape) { string propertyName; if (contract.ContractType == JsonContractType.Primitive) { JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract; if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTime || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeNullable) { escape = false; StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); DateTimeUtils.WriteDateTimeString(sw, (DateTime)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); return sw.ToString(); } else if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffset || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffsetNullable) { escape = false; StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); DateTimeUtils.WriteDateTimeOffsetString(sw, (DateTimeOffset)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); return sw.ToString(); } else { escape = true; return Convert.ToString(name, CultureInfo.InvariantCulture); } } else if (TryConvertToString(name, name.GetType(), out propertyName)) { escape = true; return propertyName; } else { escape = true; return name.ToString(); } }
private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { writer.WriteStartObject(); bool isReference = ResolveIsReference(contract, member, collectionContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Objects); if (isReference) { WriteReferenceIdProperty(writer, contract.UnderlyingType, value); } if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract, containerProperty)) { WriteTypeProperty(writer, contract.UnderlyingType); } }
private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, JsonContract collectionContract) { contract.InvokeOnSerializing(values, Serializer.Context); _serializeStack.Add(values); bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract); SerializeMultidimensionalArray(writer, values, contract, member, writer.Top, new int[0]); if (hasWrittenMetadataObject) writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); contract.InvokeOnSerialized(values, Serializer.Context); }
private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, JsonProperty member, JsonContract containerContract) { bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays); bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, containerContract); bool writeMetadataObject = isReference || includeTypeDetails; if (writeMetadataObject) { writer.WriteStartObject(); if (isReference) { writer.WritePropertyName(JsonTypeReflector.IdPropertyName); writer.WriteValue(GetReference(writer, values)); } if (includeTypeDetails) { WriteTypeProperty(writer, values.GetType()); } writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName); } /*if (contract.ItemContract == null) contract.ItemContract = Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object)); */ return writeMetadataObject; }
private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract) { if (ShouldWriteReference(value, null, contract)) { WriteReference(writer, value); } else { if (!CheckForCircularReference(value, null, contract)) return; SerializeStack.Add(value); converter.WriteJson(writer, value, GetInternalSerializer()); SerializeStack.RemoveAt(SerializeStack.Count - 1); } }
private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContract collectionValueContract) { contract.InvokeOnSerializing(values.UnderlyingCollection, Serializer.Context); SerializeStack.Add(values.UnderlyingCollection); bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays); bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionValueContract); if (isReference || includeTypeDetails) { writer.WriteStartObject(); if (isReference) { writer.WritePropertyName(JsonTypeReflector.IdPropertyName); writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, values.UnderlyingCollection)); } if (includeTypeDetails) { WriteTypeProperty(writer, values.UnderlyingCollection.GetType()); } writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName); } JsonContract childValuesContract = Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object)); writer.WriteStartArray(); int initialDepth = writer.Top; int index = 0; // note that an error in the IEnumerable won't be caught #if !(UNITY_IPHONE || UNITY_IOS || UNITY_WEBGL || UNITY_XBOXONE || UNITY_XBOX360 || UNITY_PS4 || UNITY_PS3 || UNITY_WII) || (UNITY_IOS || UNITY_WEBGL || UNITY_XBOXONE || UNITY_XBOX360 || UNITY_PS4 || UNITY_PS3 || UNITY_WII && !(UNITY_3_5 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3)) foreach (object value in values) { try { JsonContract valueContract = GetContractSafe(value); if (ShouldWriteReference(value, null, valueContract)) { WriteReference(writer, value); } else { if (CheckForCircularReference(value, null, contract)) { SerializeValue(writer, value, valueContract, null, childValuesContract); } } } catch (Exception ex) { if (IsErrorHandled(values.UnderlyingCollection, contract, index, ex)) HandleError(writer, initialDepth); else throw; } finally { index++; } } #else values.ForEach(value => { try { JsonContract valueContract = GetContractSafe(value); if (ShouldWriteReference(value, null, valueContract)) { WriteReference(writer, value); } else { if (CheckForCircularReference(value, null, contract)) { SerializeValue(writer, value, valueContract, null, childValuesContract); } } } catch (Exception ex) { if (IsErrorHandled(values.UnderlyingCollection, contract, index, ex)) HandleError(writer, initialDepth); else throw; } finally { index++; } }); #endif writer.WriteEndArray(); if (isReference || includeTypeDetails) { writer.WriteEndObject(); } SerializeStack.RemoveAt(SerializeStack.Count - 1); contract.InvokeOnSerialized(values.UnderlyingCollection, Serializer.Context); }
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContract collectionValueContract) { contract.InvokeOnSerializing(value, Serializer.Context); SerializeStack.Add(value); writer.WriteStartObject(); bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects); if (isReference) { writer.WritePropertyName(JsonTypeReflector.IdPropertyName); writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, value)); } if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract)) { WriteTypeProperty(writer, contract.UnderlyingType); } int initialDepth = writer.Top; foreach (JsonProperty property in contract.Properties) { try { if (!property.Ignored && property.Readable && ShouldSerialize(property, value) && IsSpecified(property, value)) { object memberValue = property.ValueProvider.GetValue(value); JsonContract memberContract = GetContractSafe(memberValue); WriteMemberInfoProperty(writer, memberValue, property, memberContract); } } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, ex)) HandleError(writer, initialDepth); else throw; } } writer.WriteEndObject(); SerializeStack.RemoveAt(SerializeStack.Count - 1); contract.InvokeOnSerialized(value, Serializer.Context); }
private bool CheckForCircularReference(object value, ReferenceLoopHandling? referenceLoopHandling, JsonContract contract) { if (value == null || contract is JsonPrimitiveContract) return true; if (SerializeStack.IndexOf(value) != -1) { var selfRef = (value is Vector2 || value is Vector3 || value is Vector4 || value is Color || value is Color32) ? ReferenceLoopHandling.Ignore : referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling); switch (selfRef) { case ReferenceLoopHandling.Error: throw new JsonSerializationException("Self referencing loop detected for type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); case ReferenceLoopHandling.Ignore: return false; case ReferenceLoopHandling.Serialize: return true; default: throw new InvalidOperationException("Unexpected ReferenceLoopHandling value: '{0}'".FormatWith(CultureInfo.InvariantCulture, Serializer.ReferenceLoopHandling)); } } return true; }
private void WriteMemberInfoProperty(JsonWriter writer, object memberValue, JsonProperty property, JsonContract contract) { string propertyName = property.PropertyName; object defaultValue = property.DefaultValue; if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && memberValue == null) return; if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore) && MiscellaneousUtils.ValueEquals(memberValue, defaultValue)) return; if (ShouldWriteReference(memberValue, property, contract)) { writer.WritePropertyName(propertyName); WriteReference(writer, memberValue); return; } if (!CheckForCircularReference(memberValue, property.ReferenceLoopHandling, contract)) return; if (memberValue == null && property.Required == Required.Always) throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); writer.WritePropertyName(propertyName); SerializeValue(writer, memberValue, contract, property, null); }
private void OnSerialized(JsonWriter writer, JsonContract contract, object value) { if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); contract.InvokeOnSerialized(value, Serializer._context); }
private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContract collectionValueContract) { if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, typeNameHandlingFlag)) return true; if (member != null) { if ((member.TypeNameHandling ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto // instance and property type are different && contract.UnderlyingType != member.PropertyType) { JsonContract memberTypeContract = Serializer.ContractResolver.ResolveContract(member.PropertyType); // instance type and the property's type's contract default type are different (no need to put the type in JSON because the type will be created by default) if (contract.UnderlyingType != memberTypeContract.CreatedType) return true; } } else if (collectionValueContract != null) { if (Serializer.TypeNameHandling == TypeNameHandling.Auto && contract.UnderlyingType != collectionValueContract.UnderlyingType) return true; } return false; }
private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, out JsonContract memberContract, out object memberValue) { if (!property.Ignored && property.Readable && ShouldSerialize(writer, property, value) && IsSpecified(writer, property, value)) { if (property.PropertyContract == null) property.PropertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType); memberValue = property.ValueProvider.GetValue(value); memberContract = (property.PropertyContract.IsSealed) ? property.PropertyContract : GetContractSafe(memberValue); if (ShouldWriteProperty(memberValue, property)) { if (ShouldWriteReference(memberValue, property, memberContract, contract, member)) { property.WritePropertyName(writer); WriteReference(writer, memberValue); return false; } if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member)) return false; if (memberValue == null) { JsonObjectContract objectContract = contract as JsonObjectContract; Required resolvedRequired = property._required ?? ((objectContract != null) ? objectContract.ItemRequired : null) ?? Required.Default; if (resolvedRequired == Required.Always) throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null); } return true; } } memberContract = null; memberValue = null; return false; }
private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContract collectionValueContract) { contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context); SerializeStack.Add(values.UnderlyingDictionary); writer.WriteStartObject(); bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects); if (isReference) { writer.WritePropertyName(JsonTypeReflector.IdPropertyName); writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, values.UnderlyingDictionary)); } if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract)) { WriteTypeProperty(writer, values.UnderlyingDictionary.GetType()); } JsonContract childValuesContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object)); int initialDepth = writer.Top; // Mono Unity 3.0 fix IDictionary d = values; foreach (DictionaryEntry entry in d) { string propertyName = GetPropertyName(entry); propertyName = (contract.PropertyNameResolver != null) ? contract.PropertyNameResolver(propertyName) : propertyName; try { object value = entry.Value; JsonContract valueContract = GetContractSafe(value); if (ShouldWriteReference(value, null, valueContract)) { writer.WritePropertyName(propertyName); WriteReference(writer, value); } else { if (!CheckForCircularReference(value, null, contract)) continue; writer.WritePropertyName(propertyName); SerializeValue(writer, value, valueContract, null, childValuesContract); } } catch (Exception ex) { if (IsErrorHandled(values.UnderlyingDictionary, contract, propertyName, ex)) HandleError(writer, initialDepth); else throw; } } writer.WriteEndObject(); SerializeStack.RemoveAt(SerializeStack.Count - 1); contract.InvokeOnSerialized(values.UnderlyingDictionary, Serializer.Context); }
private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty) { if (ShouldWriteReference(value, null, contract, collectionContract, containerProperty)) { WriteReference(writer, value); } else { if (!CheckForCircularReference(writer, value, null, contract, collectionContract, containerProperty)) return; _serializeStack.Add(value); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Started serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null); converter.WriteJson(writer, value, GetInternalSerializer()); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null); _serializeStack.RemoveAt(_serializeStack.Count - 1); } }
private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContract collectionValueContract) { if (contract.UnderlyingType == typeof(byte[])) { bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract); if (includeTypeDetails) { writer.WriteStartObject(); WriteTypeProperty(writer, contract.CreatedType); writer.WritePropertyName(JsonTypeReflector.ValuePropertyName); writer.WriteValue(value); writer.WriteEndObject(); return; } } writer.WriteValue(value); }
private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) { TypeNameHandling resolvedTypeNameHandling = ((member != null) ? member.TypeNameHandling : null) ?? ((containerProperty != null) ? containerProperty.ItemTypeNameHandling : null) ?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null) ?? Serializer._typeNameHandling; if (HasFlag(resolvedTypeNameHandling, typeNameHandlingFlag)) return true; // instance type and the property's type's contract default type are different (no need to put the type in JSON because the type will be created by default) if (HasFlag(resolvedTypeNameHandling, TypeNameHandling.Auto)) { if (member != null) { if (contract.UnderlyingType != member.PropertyContract.CreatedType) return true; } else if (containerContract != null) { if (containerContract.ItemContract == null || contract.UnderlyingType != containerContract.ItemContract.CreatedType) return true; } else if (_rootContract != null && _serializeStack.Count == 1) { if (contract.UnderlyingType != _rootContract.CreatedType) return true; } } return false; }
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) { if (value == null) { writer.WriteNull(); return; } JsonConverter converter; if ((((converter = (member != null) ? member.Converter : null) != null) || ((converter = (containerProperty != null) ? containerProperty.ItemConverter : null) != null) || ((converter = (containerContract != null) ? containerContract.ItemConverter : null) != null) || ((converter = valueContract.Converter) != null) || ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null) || ((converter = valueContract.InternalConverter) != null)) && converter.CanWrite) { SerializeConvertable(writer, converter, value, valueContract, containerContract, containerProperty); return; } switch (valueContract.ContractType) { case JsonContractType.Object: SerializeObject(writer, value, (JsonObjectContract)valueContract, member, containerContract, containerProperty); break; case JsonContractType.Array: JsonArrayContract arrayContract = (JsonArrayContract) valueContract; if (!arrayContract.IsMultidimensionalArray) SerializeList(writer, (IEnumerable)value, arrayContract, member, containerContract, containerProperty); else SerializeMultidimensionalArray(writer, (Array)value, arrayContract, member, containerContract, containerProperty); break; case JsonContractType.Primitive: SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, containerContract, containerProperty); break; case JsonContractType.String: SerializeString(writer, value, (JsonStringContract)valueContract); break; case JsonContractType.Dictionary: JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) valueContract; SerializeDictionary(writer, (value is IDictionary) ? (IDictionary) value : dictionaryContract.CreateWrapper(value), dictionaryContract, member, containerContract, containerProperty); break; case JsonContractType.Dynamic: SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty); break; case JsonContractType.Linq: ((JToken) value).WriteTo(writer, Serializer.Converters.ToArray()); break; } }
private JToken CreateJToken(JsonReader reader, JsonContract contract) { ValidationUtils.ArgumentNotNull(reader, "reader"); if (contract != null && contract.UnderlyingType == typeof(JRaw)) { return JRaw.Create(reader); } else { JToken token; using (JTokenWriter writer = new JTokenWriter()) { writer.WriteToken(reader); token = writer.Token; } return token; } }
private bool? ResolveIsReference(JsonContract contract, JsonProperty property, JsonContainerContract collectionContract, JsonProperty containerProperty) { bool? isReference = null; // value could be coming from a dictionary or array and not have a property if (property != null) isReference = property.IsReference; if (isReference == null && containerProperty != null) isReference = containerProperty.ItemIsReference; if (isReference == null && collectionContract != null) isReference = collectionContract.ItemIsReference; if (isReference == null) isReference = contract.IsReference; return isReference; }
private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) { if (contract is JsonLinqContract) return CreateJToken(reader, contract); do { switch (reader.TokenType) { // populate a typed object or generic dictionary/array // depending upon whether an objectType was supplied case JsonToken.StartObject: return CreateObject(reader, objectType, contract, member, existingValue); case JsonToken.StartArray: return CreateList(reader, objectType, contract, member, existingValue, null); case JsonToken.Integer: case JsonToken.Float: case JsonToken.Boolean: case JsonToken.Date: case JsonToken.Bytes: return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType); case JsonToken.String: // convert empty string to null automatically for nullable types if (string.IsNullOrEmpty((string)reader.Value) && objectType != null && ReflectionUtils.IsNullableType(objectType)) return null; // string that needs to be returned as a byte array should be base 64 decoded if (objectType == typeof(byte[])) return Convert.FromBase64String((string)reader.Value); return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType); case JsonToken.StartConstructor: case JsonToken.EndConstructor: string constructorName = reader.Value.ToString(); return constructorName; case JsonToken.Null: case JsonToken.Undefined: if (objectType == typeof(DBNull)) return DBNull.Value; return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType); case JsonToken.Raw: return new JRaw((string)reader.Value); case JsonToken.Comment: // ignore break; default: throw new JsonSerializationException("Unexpected token while deserializing object: " + reader.TokenType); } } while (reader.Read()); throw new JsonSerializationException("Unexpected end when deserializing object."); }
private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract, JsonProperty containerProperty) { if (value == null) return false; if (valueContract.ContractType == JsonContractType.Primitive || valueContract.ContractType == JsonContractType.String) return false; bool? isReference = ResolveIsReference(valueContract, property, collectionContract, containerProperty); if (isReference == null) { if (valueContract.ContractType == JsonContractType.Array) isReference = HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays); else isReference = HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Objects); } if (!isReference.Value) return false; return Serializer.GetReferenceResolver().IsReferenced(this, value); }
private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) { CheckedRead(reader); string id = null; if (reader.TokenType == JsonToken.PropertyName) { bool specialProperty; do { string propertyName = reader.Value.ToString(); if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal)) { CheckedRead(reader); if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null) throw new JsonSerializationException("JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName)); string reference = (reader.Value != null) ? reader.Value.ToString() : null; CheckedRead(reader); if (reference != null) { if (reader.TokenType == JsonToken.PropertyName) throw new JsonSerializationException("Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName)); return Serializer.ReferenceResolver.ResolveReference(this, reference); } else { specialProperty = true; } } else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal)) { CheckedRead(reader); string qualifiedTypeName = reader.Value.ToString(); CheckedRead(reader); if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) != TypeNameHandling.None) { string typeName; string assemblyName; ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName); Type specifiedType; try { specifiedType = Serializer.Binder.BindToType(assemblyName, typeName); } catch (Exception ex) { throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex); } if (specifiedType == null) throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName)); if (objectType != null && !objectType.IsAssignableFrom(specifiedType)) throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName)); objectType = specifiedType; contract = GetContractSafe(specifiedType); } specialProperty = true; } else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal)) { CheckedRead(reader); id = (reader.Value != null) ? reader.Value.ToString() : null; CheckedRead(reader); specialProperty = true; } else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal)) { CheckedRead(reader); object list = CreateList(reader, objectType, contract, member, existingValue, id); CheckedRead(reader); return list; } else { specialProperty = false; } } while (specialProperty && reader.TokenType == JsonToken.PropertyName); } if (!HasDefinedType(objectType)) return CreateJObject(reader); if (contract == null) throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); JsonDictionaryContract dictionaryContract = contract as JsonDictionaryContract; if (dictionaryContract != null) { if (existingValue == null) return CreateAndPopulateDictionary(reader, dictionaryContract, id); return PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, id); } JsonObjectContract objectContract = contract as JsonObjectContract; if (objectContract != null) { if (existingValue == null) return CreateAndPopulateObject(reader, objectContract, id); return PopulateObject(existingValue, reader, objectContract, id); } JsonPrimitiveContract primitiveContract = contract as JsonPrimitiveContract; if (primitiveContract != null) { // if the content is inside $value then read past it if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal)) { CheckedRead(reader); object value = CreateValueInternal(reader, objectType, primitiveContract, member, existingValue); CheckedRead(reader); return value; } } #if !((UNITY_WINRT && !UNITY_EDITOR) || (UNITY_WP8 || UNITY_WP_8_1)) JsonISerializableContract serializableContract = contract as JsonISerializableContract; if (serializableContract != null) { return CreateISerializable(reader, serializableContract, id); } #endif throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); }
private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty) { if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String) return true; ReferenceLoopHandling? referenceLoopHandling = null; if (property != null) referenceLoopHandling = property.ReferenceLoopHandling; if (referenceLoopHandling == null && containerProperty != null) referenceLoopHandling = containerProperty.ItemReferenceLoopHandling; if (referenceLoopHandling == null && containerContract != null) referenceLoopHandling = containerContract.ItemReferenceLoopHandling; if (_serializeStack.IndexOf(value) != -1) { string message = "Self referencing loop detected"; if (property != null) message += " for property '{0}'".FormatWith(CultureInfo.InvariantCulture, property.PropertyName); message += " with type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()); var selfRef = (value is Vector2 || value is Vector3 || value is Vector4 || value is Color || value is Color32) ? ReferenceLoopHandling.Ignore : referenceLoopHandling.GetValueOrDefault(Serializer._referenceLoopHandling); switch (selfRef) { case ReferenceLoopHandling.Error: throw JsonSerializationException.Create(null, writer.ContainerPath, message, null); case ReferenceLoopHandling.Ignore: if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Skipping serializing self referenced value."), null); return false; case ReferenceLoopHandling.Serialize: if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Serializing self referenced value."), null); return true; } } return true; }
private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string reference) { object value; if (HasDefinedType(objectType)) { JsonArrayContract arrayContract = EnsureArrayContract(objectType, contract); if (existingValue == null || objectType == typeof(BitArray)) value = CreateAndPopulateList(reader, reference, arrayContract); else value = PopulateList(arrayContract.CreateWrapper(existingValue), reader, reference, arrayContract); } else { value = CreateJToken(reader, contract); } return value; }
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContract collectionValueContract) { JsonConverter converter = (member != null) ? member.Converter : null; if (value == null) { writer.WriteNull(); return; } if ((converter != null || ((converter = valueContract.Converter) != null) || ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null) || ((converter = valueContract.InternalConverter) != null)) && converter.CanWrite) { SerializeConvertable(writer, converter, value, valueContract); } else if (valueContract is JsonPrimitiveContract) { SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, collectionValueContract); } else if (valueContract is JsonStringContract) { SerializeString(writer, value, (JsonStringContract)valueContract); } else if (valueContract is JsonObjectContract) { SerializeObject(writer, value, (JsonObjectContract)valueContract, member, collectionValueContract); } else if (valueContract is JsonDictionaryContract) { JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)valueContract; SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionValueContract); } else if (valueContract is JsonArrayContract) { JsonArrayContract arrayContract = (JsonArrayContract)valueContract; if (!arrayContract.IsMultidimensionalArray) SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionValueContract); else SerializeMultidimensionalArray(writer, (Array)value, arrayContract, member, collectionValueContract); } else if (valueContract is JsonLinqContract) { ((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null); } #if !((UNITY_WINRT && !UNITY_EDITOR) || (UNITY_WP8 || UNITY_WP_8_1)) else if (valueContract is JsonISerializableContract) { SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract); } #endif }