// Token: 0x06000BEB RID: 3051 // RVA: 0x0004663C File Offset: 0x0004483C public void Serialize(JsonWriter jsonWriter, object value, Type objectType) { if (jsonWriter == null) { throw new ArgumentNullException("jsonWriter"); } this._rootContract = ((objectType != null) ? this.Serializer._contractResolver.ResolveContract(objectType) : null); this._rootLevel = this._serializeStack.Count + 1; JsonContract contractSafe = this.GetContractSafe(value); try { this.SerializeValue(jsonWriter, value, contractSafe, null, null, null); } catch (Exception ex) { if (!base.IsErrorHandled(null, contractSafe, null, null, jsonWriter.Path, ex)) { base.ClearErrorContext(); throw; } this.HandleError(jsonWriter, 0); } finally { this._rootContract = null; } }
public void Serialize(JsonWriter jsonWriter, object value, Type objectType) { if (jsonWriter == null) throw new ArgumentNullException("jsonWriter"); if (objectType != null) _rootContract = Serializer._contractResolver.ResolveContract(objectType); JsonContract contract = GetContractSafe(value); try { SerializeValue(jsonWriter, value, contract, null, null, null); } catch (Exception ex) { if (IsErrorHandled(null, contract, null, null, jsonWriter.Path, ex)) { HandleError(jsonWriter, 0); } else { // clear context in case serializer is being used inside a converter // if the converter wraps the error then not clearing the context will cause this error: // "Current error context error is different to requested error." ClearErrorContext(); throw; } } }
private static void AddContractStackCallbacks (JsonContract contract) { contract.OnDeserializingCallbacks.Add((o, ctx) => JsonLinkedContext.Get(ctx).PushObject(o)); contract.OnDeserializingCallbacks.Add((o, ctx) => JsonLinkedContext.Get(ctx).SetOwner(o)); contract.OnDeserializedCallbacks.Add((o, ctx) => JsonLinkedContext.Get(ctx).PopObject(o)); contract.OnSerializingCallbacks.Add((o, ctx) => JsonLinkedContext.Get(ctx).PushObject(o)); contract.OnSerializedCallbacks.Add((o, ctx) => JsonLinkedContext.Get(ctx).PopObject(o)); }
protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, Exception ex) { ErrorContext errorContext = GetErrorContext(currentObject, keyValue, ex); contract.InvokeOnError(currentObject, Serializer.Context, errorContext); if (!errorContext.Handled) Serializer.OnError(new ErrorEventArgs(currentObject, errorContext)); return errorContext.Handled; }
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 void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) { if (value == null) { writer.WriteNull(); } else { JsonConverter converter; if (((converter = member != null ? member.Converter : (JsonConverter) null) != null || (converter = containerProperty != null ? containerProperty.ItemConverter : (JsonConverter) null) != null || ((converter = containerContract != null ? containerContract.ItemConverter : (JsonConverter) null) != null || (converter = valueContract.Converter) != null || ((converter = this.Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null || (converter = valueContract.InternalConverter) != null))) && converter.CanWrite) { this.SerializeConvertable(writer, converter, value, valueContract, containerContract, containerProperty); } else { switch (valueContract.ContractType) { case JsonContractType.Object: this.SerializeObject(writer, value, (JsonObjectContract) valueContract, member, containerContract, containerProperty); break; case JsonContractType.Array: JsonArrayContract contract1 = (JsonArrayContract) valueContract; if (!contract1.IsMultidimensionalArray) { this.SerializeList(writer, contract1.CreateWrapper(value), contract1, member, containerContract, containerProperty); break; } else { this.SerializeMultidimensionalArray(writer, (Array) value, contract1, member, containerContract, containerProperty); break; } case JsonContractType.Primitive: this.SerializePrimitive(writer, value, (JsonPrimitiveContract) valueContract, member, containerContract, containerProperty); break; case JsonContractType.String: this.SerializeString(writer, value, (JsonStringContract) valueContract); break; case JsonContractType.Dictionary: JsonDictionaryContract contract2 = (JsonDictionaryContract) valueContract; this.SerializeDictionary(writer, contract2.CreateWrapper(value), contract2, member, containerContract, containerProperty); break; case JsonContractType.Serializable: this.SerializeISerializable(writer, (ISerializable) value, (JsonISerializableContract) valueContract, member, containerContract, containerProperty); break; case JsonContractType.Linq: ((JToken) value).WriteTo(writer, this.Serializer.Converters != null ? Enumerable.ToArray<JsonConverter>((IEnumerable<JsonConverter>) this.Serializer.Converters) : (JsonConverter[]) null); break; } } } }
private void SerializeValue(JsonWriter writer, object value, JsonConverter memberConverter, JsonContract contract) { JsonConverter converter = memberConverter; if (value == null) { writer.WriteNull(); return; } if (converter != null || ((converter = contract.Converter) != null) || Serializer.HasMatchingConverter(contract.UnderlyingType, out converter)) { SerializeConvertable(writer, converter, value, contract); } else if (contract is JsonPrimitiveContract) { writer.WriteValue(value); } else if (value is JToken) { ((JToken) value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null); } else if (contract is JsonObjectContract) { SerializeObject(writer, value, (JsonObjectContract) contract); } else if (contract is JsonDictionaryContract) { SerializeDictionary(writer, (IDictionary) value, (JsonDictionaryContract) contract); } else if (contract is JsonArrayContract) { if (value is IList) { SerializeList(writer, (IList) value, (JsonArrayContract) contract); } else if (value is IEnumerable) { SerializeEnumerable(writer, (IEnumerable) value, (JsonArrayContract) contract); } else { throw new Exception( "Cannot serialize '{0}' into a JSON array. Type does not implement IEnumerable.".FormatWith( CultureInfo.InvariantCulture, value.GetType())); } } }
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); }
public void Serialize(JsonWriter jsonWriter, object value, Type objectType) { if (jsonWriter == null) throw new ArgumentNullException("jsonWriter"); _rootContract = (objectType != null) ? Serializer._contractResolver.ResolveContract(objectType) : null; _rootLevel = _serializeStack.Count + 1; JsonContract contract = GetContractSafe(value); try { if (ShouldWriteReference(value, null, contract, null, null)) { WriteReference(jsonWriter, value); } else { SerializeValue(jsonWriter, value, contract, null, null, null); } } catch (Exception ex) { if (IsErrorHandled(null, contract, null, null, jsonWriter.Path, ex)) { HandleError(jsonWriter, 0); } else { // clear context in case serializer is being used inside a converter // if the converter wraps the error then not clearing the context will cause this error: // "Current error context error is different to requested error." ClearErrorContext(); throw; } } finally { // clear root contract to ensure that if level was > 1 then it won't // accidently be used for non root values _rootContract = null; } }
public JsonContract ModifyContract(JsonContract contract) { if (contract is JsonDictionaryContract) { var dictionaryContract = contract as JsonDictionaryContract; if (typeof(GeoLocation).IsAssignableFrom(dictionaryContract.DictionaryValueType)) { dictionaryContract.PropertyNameResolver = x => x + "$$geo"; } else if (typeof(Attachment).IsAssignableFrom(dictionaryContract.DictionaryValueType)) { dictionaryContract.PropertyNameResolver = x => x + "$$attachment"; } else { dictionaryContract.PropertyNameResolver = x => TypeSuffix.GetSuffixedFieldName(x, dictionaryContract.DictionaryValueType); } dictionaryContract.Converter = new DictionaryConverter() { PropertyNameDesolver = x => x.Contains('$') ? x.Split('$')[0] : x }; } return contract; }
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, arrayContract.CreateWrapper(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, dictionaryContract.CreateWrapper(value), dictionaryContract, member, containerContract, containerProperty); break; #if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE) case JsonContractType.Dynamic: SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty); break; #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) case JsonContractType.Serializable: SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, containerContract, containerProperty); break; #endif case JsonContractType.Linq: ((JToken) value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null); break; } }
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 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); converter.WriteJson(writer, value, GetInternalSerializer()); _serializeStack.RemoveAt(_serializeStack.Count - 1); } }
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) { throw new JsonSerializationException("JSON reference {0} property must have a string value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName)); } string reference = reader.Value.ToString(); CheckedRead(reader); 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 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.ToString(); 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)); } #if !SILVERLIGHT && !PocketPC JsonISerializableContract serializableContract = contract as JsonISerializableContract; if (serializableContract != null) { return(CreateISerializable(reader, serializableContract, id)); } #endif #if !(NET35 || NET20 || WINDOWS_PHONE) JsonDynamicContract dynamicContract = contract as JsonDynamicContract; if (dynamicContract != null) { return(CreateDynamic(reader, dynamicContract, id)); } #endif throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); }
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 object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) { CheckedRead(reader); string id = null; if (reader.TokenType == JsonToken.PropertyName) { string propertyName = reader.Value.ToString(); if (propertyName.Length > 0 && propertyName[0] == '$') { // read 'special' properties // $type, $id, $ref, etc bool specialProperty; do { propertyName = reader.Value.ToString(); if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal)) { CheckedRead(reader); if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null) throw CreateSerializationException(reader, "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 CreateSerializationException(reader, "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(); 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 CreateSerializationException(reader, "Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex); } if (specifiedType == null) throw CreateSerializationException(reader, "Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName)); if (objectType != null && !objectType.IsAssignableFrom(specifiedType)) throw CreateSerializationException(reader, "Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName)); objectType = specifiedType; contract = GetContractSafe(specifiedType); } CheckedRead(reader); 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 CreateSerializationException(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); switch (contract.ContractType) { case JsonContractType.Object: JsonObjectContract objectContract = (JsonObjectContract) contract; if (existingValue == null) return CreateAndPopulateObject(reader, objectContract, id); return PopulateObject(existingValue, reader, objectContract, id); case JsonContractType.Primitive: JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract) contract; // 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; } break; case JsonContractType.Dictionary: JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) contract; if (existingValue == null) return CreateAndPopulateDictionary(reader, dictionaryContract, id); return PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, id); #if !(NET35 || NET20 || WINDOWS_PHONE) case JsonContractType.Dynamic: JsonDynamicContract dynamicContract = (JsonDynamicContract) contract; return CreateDynamic(reader, dynamicContract, id); #endif #if !SILVERLIGHT && !PocketPC && !NETFX_CORE case JsonContractType.Serializable: JsonISerializableContract serializableContract = (JsonISerializableContract) contract; return CreateISerializable(reader, serializableContract, id); #endif } throw CreateSerializationException(reader, @"Cannot deserialize JSON object (i.e. {{""name"":""value""}}) into type '{0}'. The deserialized type should be a normal .NET type (i.e. not a primitive type like integer, not a collection type like an array or List<T>) or a dictionary type (i.e. Dictionary<TKey, TValue>). To force JSON objects to deserialize add the JsonObjectAttribute to the type.".FormatWith(CultureInfo.InvariantCulture, objectType)); }
private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { object underlyingDictionary = values is IWrappedDictionary wrappedDictionary ? 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; // Manual use of IDictionaryEnumerator instead of foreach to avoid DictionaryEntry box allocations. IDictionaryEnumerator e = values.GetEnumerator(); try { while (e.MoveNext()) { DictionaryEntry entry = e.Entry; string propertyName = GetPropertyName(writer, entry.Key, contract.KeyContract, out bool escape); propertyName = (contract.DictionaryKeyResolver != null) ? contract.DictionaryKeyResolver(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; } } } } finally { (e as IDisposable)?.Dispose(); } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, underlyingDictionary); }
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 (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 bool CheckForCircularReference(object value, ReferenceLoopHandling?referenceLoopHandling, JsonContract contract) { if (value == null || contract is JsonPrimitiveContract) { return(true); } if (SerializeStack.IndexOf(value) != -1) { switch (referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling)) { 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 object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) { CheckedRead(reader); string text = null; if (reader.TokenType == JsonToken.PropertyName) { bool flag; do { string a = reader.Value.ToString(); if (string.Equals(a, "$ref", 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, "$ref")); } string text2 = ((reader.Value != null) ? reader.Value.ToString() : null); CheckedRead(reader); if (text2 != 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, "$ref")); } return(base.Serializer.ReferenceResolver.ResolveReference(this, text2)); } flag = true; } else if (string.Equals(a, "$type", StringComparison.Ordinal)) { CheckedRead(reader); string text3 = reader.Value.ToString(); CheckedRead(reader); if ((member?.TypeNameHandling ?? base.Serializer.TypeNameHandling) != 0) { ReflectionUtils.SplitFullyQualifiedTypeName(text3, out var typeName, out var assemblyName); Type type; try { type = base.Serializer.Binder.BindToType(assemblyName, typeName); } catch (Exception innerException) { throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, text3), innerException); } if (type == null) { throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, text3)); } if (!(objectType?.IsAssignableFrom(type) ?? true)) { throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, type.AssemblyQualifiedName, objectType.AssemblyQualifiedName)); } objectType = type; contract = GetContractSafe(type); } flag = true; } else if (string.Equals(a, "$id", StringComparison.Ordinal)) { CheckedRead(reader); text = ((reader.Value != null) ? reader.Value.ToString() : null); CheckedRead(reader); flag = true; } else { if (string.Equals(a, "$values", StringComparison.Ordinal)) { CheckedRead(reader); object result = CreateList(reader, objectType, contract, member, existingValue, text); CheckedRead(reader); return(result); } flag = false; } }while (flag && 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 jsonDictionaryContract = contract as JsonDictionaryContract; if (jsonDictionaryContract != null) { if (existingValue == null) { return(CreateAndPopulateDictionary(reader, jsonDictionaryContract, text)); } return(PopulateDictionary(jsonDictionaryContract.CreateWrapper(existingValue), reader, jsonDictionaryContract, text)); } JsonObjectContract jsonObjectContract = contract as JsonObjectContract; if (jsonObjectContract != null) { if (existingValue == null) { return(CreateAndPopulateObject(reader, jsonObjectContract, text)); } return(PopulateObject(existingValue, reader, jsonObjectContract, text)); } JsonPrimitiveContract jsonPrimitiveContract = contract as JsonPrimitiveContract; if (jsonPrimitiveContract != null && reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), "$value", StringComparison.Ordinal)) { CheckedRead(reader); object result2 = CreateValueInternal(reader, objectType, jsonPrimitiveContract, member, existingValue); CheckedRead(reader); return(result2); } JsonISerializableContract jsonISerializableContract = contract as JsonISerializableContract; if (jsonISerializableContract != null) { return(CreateISerializable(reader, jsonISerializableContract, text)); } throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); }
private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id) { ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); Type underlyingType = contract.UnderlyingType; IDictionary <JsonProperty, object> dictionary = ResolvePropertyAndConstructorValues(contract, reader, underlyingType); IDictionary <ParameterInfo, object> dictionary2 = ((IEnumerable <ParameterInfo>)constructorInfo.GetParameters()).ToDictionary((Func <ParameterInfo, ParameterInfo>)((ParameterInfo p) => p), (Func <ParameterInfo, object>)((ParameterInfo p) => null)); IDictionary <JsonProperty, object> dictionary3 = new Dictionary <JsonProperty, object>(); foreach (KeyValuePair <JsonProperty, object> item in dictionary) { ParameterInfo key = dictionary2.ForgivingCaseSensitiveFind((KeyValuePair <ParameterInfo, object> kv) => kv.Key.Name, item.Key.UnderlyingName).Key; if (key != null) { dictionary2[key] = item.Value; } else { dictionary3.Add(item); } } object obj = constructorInfo.Invoke(dictionary2.Values.ToArray()); if (id != null) { base.Serializer.ReferenceResolver.AddReference(this, id, obj); } contract.InvokeOnDeserializing(obj, base.Serializer.Context); foreach (KeyValuePair <JsonProperty, object> item2 in dictionary3) { JsonProperty key2 = item2.Key; object value = item2.Value; if (ShouldSetPropertyValue(item2.Key, item2.Value)) { key2.ValueProvider.SetValue(obj, value); } else { if (key2.Writable || value == null) { continue; } JsonContract jsonContract = base.Serializer.ContractResolver.ResolveContract(key2.PropertyType); if (jsonContract is JsonArrayContract) { JsonArrayContract jsonArrayContract = jsonContract as JsonArrayContract; object value2 = key2.ValueProvider.GetValue(obj); if (value2 == null) { continue; } IWrappedCollection wrappedCollection = jsonArrayContract.CreateWrapper(value2); IWrappedCollection wrappedCollection2 = jsonArrayContract.CreateWrapper(value); foreach (object item3 in wrappedCollection2) { wrappedCollection.Add(item3); } } else { if (!(jsonContract is JsonDictionaryContract)) { continue; } JsonDictionaryContract jsonDictionaryContract = jsonContract as JsonDictionaryContract; object value3 = key2.ValueProvider.GetValue(obj); if (value3 == null) { continue; } IWrappedDictionary wrappedDictionary = jsonDictionaryContract.CreateWrapper(value3); IWrappedDictionary wrappedDictionary2 = jsonDictionaryContract.CreateWrapper(value); foreach (DictionaryEntry item4 in wrappedDictionary2) { wrappedDictionary.Add(item4.Key, item4.Value); } } } } contract.InvokeOnDeserialized(obj, base.Serializer.Context); return(obj); }
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, 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 string GetPropertyName(JsonWriter writer, object name, JsonContract contract, out bool escape) { if (contract.ContractType == JsonContractType.Primitive) { JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract; switch (primitiveContract.TypeCode) { case PrimitiveTypeCode.DateTime: case PrimitiveTypeCode.DateTimeNullable: { DateTime dt = DateTimeUtils.EnsureDateTime((DateTime)name, writer.DateTimeZoneHandling); escape = false; StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); DateTimeUtils.WriteDateTimeString(sw, dt, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); return(sw.ToString()); } #if HAVE_DATE_TIME_OFFSET case PrimitiveTypeCode.DateTimeOffset: case PrimitiveTypeCode.DateTimeOffsetNullable: { escape = false; StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); DateTimeUtils.WriteDateTimeOffsetString(sw, (DateTimeOffset)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); return(sw.ToString()); } #endif case PrimitiveTypeCode.Double: case PrimitiveTypeCode.DoubleNullable: { double d = (double)name; escape = false; return(d.ToString("R", CultureInfo.InvariantCulture)); } case PrimitiveTypeCode.Single: case PrimitiveTypeCode.SingleNullable: { float f = (float)name; escape = false; return(f.ToString("R", CultureInfo.InvariantCulture)); } default: { escape = true; if (primitiveContract.IsEnum && EnumUtils.TryToString(primitiveContract.NonNullableUnderlyingType, name, false, out string enumName)) { return(enumName); } return(Convert.ToString(name, CultureInfo.InvariantCulture)); } } } else if (TryConvertToString(name, name.GetType(), out string propertyName)) { escape = true; return(propertyName); } else { escape = true; return(name.ToString()); } }
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 object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id) { ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); Type underlyingType = contract.UnderlyingType; IDictionary <JsonProperty, object> dictionary = ResolvePropertyAndConstructorValues(contract, reader, underlyingType); IDictionary <ParameterInfo, object> dictionary2 = ((IEnumerable <ParameterInfo>)constructorInfo.GetParameters()).ToDictionary((Func <ParameterInfo, ParameterInfo>)((ParameterInfo p) => p), (Func <ParameterInfo, object>)((ParameterInfo p) => null)); IDictionary <JsonProperty, object> dictionary3 = new Dictionary <JsonProperty, object>(); foreach (KeyValuePair <JsonProperty, object> item in dictionary) { ParameterInfo key = dictionary2.ForgivingCaseSensitiveFind((KeyValuePair <ParameterInfo, object> kv) => kv.Key.Name, item.Key.UnderlyingName).Key; if (key != null) { dictionary2[key] = item.Value; } else { dictionary3.Add(item); } } object obj = constructorInfo.Invoke(dictionary2.Values.ToArray()); if (id != null) { base.Serializer.ReferenceResolver.AddReference(this, id, obj); } contract.InvokeOnDeserializing(obj, base.Serializer.Context); foreach (KeyValuePair <JsonProperty, object> item2 in dictionary3) { JsonProperty key2 = item2.Key; object value = item2.Value; if (ShouldSetPropertyValue(item2.Key, item2.Value)) { key2.ValueProvider.SetValue(obj, value); } else if (!key2.Writable && value != null) { JsonContract jsonContract = base.Serializer.ContractResolver.ResolveContract(key2.PropertyType); if (jsonContract is JsonArrayContract) { JsonArrayContract jsonArrayContract = jsonContract as JsonArrayContract; object value2 = key2.ValueProvider.GetValue(obj); if (value2 != null) { IWrappedCollection wrappedCollection = jsonArrayContract.CreateWrapper(value2); IWrappedCollection wrappedCollection2 = jsonArrayContract.CreateWrapper(value); IEnumerator enumerator3 = wrappedCollection2.GetEnumerator(); try { while (enumerator3.MoveNext()) { object current3 = enumerator3.Current; wrappedCollection.Add(current3); } } finally { IDisposable disposable; if ((disposable = (enumerator3 as IDisposable)) != null) { disposable.Dispose(); } } } } else if (jsonContract is JsonDictionaryContract) { JsonDictionaryContract jsonDictionaryContract = jsonContract as JsonDictionaryContract; object value3 = key2.ValueProvider.GetValue(obj); if (value3 != null) { IWrappedDictionary wrappedDictionary = jsonDictionaryContract.CreateWrapper(value3); IWrappedDictionary wrappedDictionary2 = jsonDictionaryContract.CreateWrapper(value); IDictionaryEnumerator enumerator4 = wrappedDictionary2.GetEnumerator(); try { while (enumerator4.MoveNext()) { DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator4.Current; wrappedDictionary.Add(dictionaryEntry.Key, dictionaryEntry.Value); } } finally { IDisposable disposable2; if ((disposable2 = (enumerator4 as IDisposable)) != null) { disposable2.Dispose(); } } } } } } contract.InvokeOnDeserialized(obj, base.Serializer.Context); return(obj); }
private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) { if (contract != null && contract.ContractType == JsonContractType.Linq) 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, reader.Value, CultureInfo.InvariantCulture, contract, objectType); case JsonToken.String: // convert empty string to null automatically for nullable types if (string.IsNullOrEmpty((string)reader.Value) && objectType != typeof(string) && objectType != typeof(object) && contract.IsNullable) 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, reader.Value, CultureInfo.InvariantCulture, contract, objectType); case JsonToken.StartConstructor: case JsonToken.EndConstructor: string constructorName = reader.Value.ToString(); return constructorName; case JsonToken.Null: case JsonToken.Undefined: #if !NETFX_CORE if (objectType == typeof (DBNull)) return DBNull.Value; #endif return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType); case JsonToken.Raw: return new JRaw((string) reader.Value); case JsonToken.Comment: // ignore break; default: throw CreateSerializationException(reader, "Unexpected token while deserializing object: " + reader.TokenType); } } while (reader.Read()); throw CreateSerializationException(reader, "Unexpected end when deserializing object."); }
private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { OnSerializing(writer, contract, value); _serializeStack.Add(value); WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); int initialDepth = writer.Top; for (int index = 0; index < contract.Properties.Count; index++) { JsonProperty property = contract.Properties[index]; // only write non-dynamic properties that have an explicit attribute if (property.HasMemberAttribute) { try { object memberValue; JsonContract memberContract; if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) { continue; } property.WritePropertyName(writer); SerializeValue(writer, memberValue, memberContract, property, contract, member); } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } } } foreach (string memberName in value.GetDynamicMemberNames()) { object memberValue; if (contract.TryGetMember(value, memberName, out memberValue)) { try { JsonContract valueContract = GetContractSafe(memberValue); if (!ShouldWriteDynamicProperty(memberValue)) { continue; } if (CheckForCircularReference(writer, memberValue, null, valueContract, contract, member)) { string resolvedPropertyName = (contract.PropertyNameResolver != null) ? contract.PropertyNameResolver(memberName) : memberName; writer.WritePropertyName(resolvedPropertyName); SerializeValue(writer, memberValue, valueContract, null, contract, member); } } catch (Exception ex) { if (IsErrorHandled(value, contract, memberName, null, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, value); }
private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string reference) { object value; if (HasDefinedType(objectType)) { JsonArrayContract arrayContract = EnsureArrayContract(reader, objectType, contract); if (existingValue == null) value = CreateAndPopulateList(reader, reference, arrayContract); else value = PopulateList(arrayContract.CreateWrapper(existingValue), reader, reference, arrayContract); } else { value = CreateJToken(reader, contract); } return value; }
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 SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { IWrappedCollection wrappedCollection = values as IWrappedCollection; object underlyingList = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : values; OnSerializing(writer, contract, underlyingList); _serializeStack.Add(underlyingList); bool hasWrittenMetadataObject = WriteStartArray(writer, underlyingList, contract, member, collectionContract, containerProperty); writer.WriteStartArray(); int initialDepth = writer.Top; int index = 0; // note that an error in the IEnumerable won't be caught foreach (object value in values) { try { JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value); if (ShouldWriteReference(value, null, valueContract, contract, member)) { WriteReference(writer, value); } else { if (CheckForCircularReference(writer, value, null, valueContract, contract, member)) { SerializeValue(writer, value, valueContract, null, contract, member); } } } catch (Exception ex) { if (IsErrorHandled(underlyingList, contract, index, null, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } finally { index++; } } writer.WriteEndArray(); if (hasWrittenMetadataObject) { writer.WriteEndObject(); } _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, underlyingList); }
private void InitializeContract(JsonContract contract) { JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.UnderlyingType); if (containerAttribute != null) { contract.IsReference = containerAttribute._isReference; } #if !PocketPC && !NET20 else { DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.UnderlyingType); // doesn't have a null value if (dataContractAttribute != null && dataContractAttribute.IsReference) { contract.IsReference = true; } } #endif contract.Converter = ResolveContractConverter(contract.UnderlyingType); // then see whether object is compadible with any of the built in converters contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.UnderlyingType); if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true) || contract.CreatedType.IsValueType) { contract.DefaultCreator = GetDefaultCreator(contract.CreatedType); contract.DefaultCreatorNonPublic = (!contract.CreatedType.IsValueType && ReflectionUtils.GetDefaultConstructor(contract.CreatedType) == null); } foreach (MethodInfo method in contract.UnderlyingType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { // compact framework errors when getting parameters for a generic method // lame, but generic methods should not be callbacks anyway if (method.ContainsGenericParameters) { continue; } Type prevAttributeType = null; ParameterInfo[] parameters = method.GetParameters(); #if !PocketPC if (IsValidCallback(method, parameters, typeof(OnSerializingAttribute), contract.OnSerializing, ref prevAttributeType)) { contract.OnSerializing = method; } if (IsValidCallback(method, parameters, typeof(OnSerializedAttribute), contract.OnSerialized, ref prevAttributeType)) { contract.OnSerialized = method; } if (IsValidCallback(method, parameters, typeof(OnDeserializingAttribute), contract.OnDeserializing, ref prevAttributeType)) { contract.OnDeserializing = method; } if (IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), contract.OnDeserialized, ref prevAttributeType)) { contract.OnDeserialized = method; } #endif if (IsValidCallback(method, parameters, typeof(OnErrorAttribute), contract.OnError, ref prevAttributeType)) { contract.OnError = method; } } }
private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { OnSerializing(writer, contract, values.UnderlyingCollection); _serializeStack.Add(values.UnderlyingCollection); bool hasWrittenMetadataObject = WriteStartArray(writer, values.UnderlyingCollection, contract, member, collectionContract, containerProperty); writer.WriteStartArray(); int initialDepth = writer.Top; int index = 0; object valuePrevious = new object(); try { // note that an error in the IEnumerable won't be caught foreach (object value in values) { try { JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value); if (ShouldWriteReference(value, null, valueContract, contract, member)) { WriteReference(writer, value); } else { if (CheckForCircularReference(writer, value, null, valueContract, contract, member)) { SerializeValue(writer, value, valueContract, null, contract, member); } } } catch (Exception ex) { if (IsErrorHandled(values.UnderlyingCollection, contract, index, null, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } finally { index++; valuePrevious = value; } } } catch (Exception e) { string msg = "valuePrevious[" + valuePrevious.ToString() + "] trying to catch COLLECTION_CHANGED"; throw new Exception(msg, e); } writer.WriteEndArray(); if (hasWrittenMetadataObject) { writer.WriteEndObject(); } _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, values.UnderlyingCollection); }
private JSchema PopulateSchema(JSchema schema, JsonContract contract, JsonProperty memberProperty, Required valueRequired) { schema.Title = GetTitle(contract.NonNullableUnderlyingType); schema.Description = GetDescription(contract.NonNullableUnderlyingType); JsonConverter converter = contract.Converter ?? contract.InternalConverter; if (converter != null) { schema.Type = null; } else { switch (contract.ContractType) { case JsonContractType.Object: if (schema.Id == null) schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false); schema.Type = AddNullType(JSchemaType.Object, valueRequired); GenerateObjectSchema(schema, contract.NonNullableUnderlyingType, (JsonObjectContract)contract); break; case JsonContractType.Array: if (schema.Id == null) schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false); schema.Type = AddNullType(JSchemaType.Array, valueRequired); schema.MinimumItems = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumItems = DataAnnotationHelpers.GetMaxLength(memberProperty); JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetCachedAttribute<JsonArrayAttribute>(contract.NonNullableUnderlyingType); bool allowNullItem = (arrayAttribute == null || arrayAttribute.AllowNullItems); Type collectionItemType = ReflectionUtils.GetCollectionItemType(contract.NonNullableUnderlyingType); if (collectionItemType != null) { schema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, null, (JsonArrayContract)contract)); } break; case JsonContractType.Primitive: schema.Type = GetJSchemaType(contract.UnderlyingType, valueRequired); if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.String)) { int minimumLength; int maximumLength; if (DataAnnotationHelpers.GetStringLength(memberProperty, out minimumLength, out maximumLength)) { schema.MinimumLength = minimumLength; schema.MaximumLength = maximumLength; } else { schema.MinimumLength = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty); } schema.Pattern = DataAnnotationHelpers.GetPattern(memberProperty); schema.Format = DataAnnotationHelpers.GetFormat(memberProperty); } if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.Number) || JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.Integer)) { double minimum; double maximum; if (DataAnnotationHelpers.GetRange(memberProperty, out minimum, out maximum)) { schema.Minimum = minimum; schema.Maximum = maximum; } } if (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.Integer) && contract.NonNullableUnderlyingType.IsEnum() && ReflectionUtils.GetAttribute<FlagsAttribute>(contract.NonNullableUnderlyingType) == null) { IList<EnumValue<long>> enumValues = EnumUtils.GetNamesAndValues<long>(contract.NonNullableUnderlyingType); foreach (EnumValue<long> enumValue in enumValues) { JToken value = JToken.FromObject(enumValue.Value); schema.Enum.Add(value); } } Type enumDataType = DataAnnotationHelpers.GetEnumDataType(memberProperty); if (enumDataType != null && CollectionUtils.IsNullOrEmpty(schema._enum)) { IList<EnumValue<long>> enumValues = EnumUtils.GetNamesAndValues<long>(enumDataType); foreach (EnumValue<long> enumValue in enumValues) { JToken value = (JSchemaTypeHelpers.HasFlag(schema.Type, JSchemaType.String)) ? enumValue.Name : JToken.FromObject(enumValue.Value); schema.Enum.Add(value); } } break; case JsonContractType.String: JSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType)) ? JSchemaType.String : AddNullType(JSchemaType.String, valueRequired); schema.Type = schemaType; schema.MinimumLength = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumLength = DataAnnotationHelpers.GetMaxLength(memberProperty); break; case JsonContractType.Dictionary: schema.Type = AddNullType(JSchemaType.Object, valueRequired); schema.MinimumProperties = DataAnnotationHelpers.GetMinLength(memberProperty); schema.MaximumProperties = DataAnnotationHelpers.GetMaxLength(memberProperty); Type keyType; Type valueType; ReflectionUtils.GetDictionaryKeyValueTypes(contract.NonNullableUnderlyingType, out keyType, out valueType); if (keyType != null) { JsonContract keyContract = ContractResolver.ResolveContract(keyType); // can be converted to a string if (keyContract.ContractType == JsonContractType.Primitive) { schema.AdditionalProperties = GenerateInternal(valueType, Required.Default, null, (JsonDictionaryContract)contract); } } break; case JsonContractType.Serializable: if (schema.Id == null) schema.Id = GetTypeId(contract.NonNullableUnderlyingType, false); schema.Type = AddNullType(JSchemaType.Object, valueRequired); schema.AllowAdditionalProperties = true; break; case JsonContractType.Dynamic: case JsonContractType.Linq: schema.Type = null; break; default: throw new JSchemaException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract)); } } return schema; }
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.ReferenceResolver.IsReferenced(this, value); }
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(property, value) && IsSpecified(property, value)) { if (property.PropertyContract == null) property.PropertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType); memberValue = property.ValueProvider.GetValue(value); memberContract = (property.PropertyContract.UnderlyingType.IsSealed()) ? property.PropertyContract : GetContractSafe(memberValue); if (ShouldWriteProperty(memberValue, property)) { if (ShouldWriteReference(memberValue, property, memberContract, contract, member)) { writer.WritePropertyName(property.PropertyName); 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 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 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 }
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 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 static TypeSchemaKey CreateKey(Required valueRequired, JsonProperty memberProperty, JsonContract contract) { int? minLength = DataAnnotationHelpers.GetMinLength(memberProperty); int? maxLength = DataAnnotationHelpers.GetMaxLength(memberProperty); TypeSchemaKey key = new TypeSchemaKey(contract.UnderlyingType, valueRequired, minLength, maxLength); return key; }
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 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++; } } writer.WriteEndArray(); if (isReference || includeTypeDetails) { writer.WriteEndObject(); } SerializeStack.RemoveAt(SerializeStack.Count - 1); contract.InvokeOnSerialized(values.UnderlyingCollection, Serializer.Context); }
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 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 && contract.UnderlyingType != member.PropertyType) { return(true); } } else if (collectionValueContract != null) { if (Serializer.TypeNameHandling == TypeNameHandling.Auto && contract.UnderlyingType != collectionValueContract.UnderlyingType) { return(true); } } return(false); }
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) { switch (referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling)) { case ReferenceLoopHandling.Error: 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()); throw JsonSerializationException.Create(null, writer.ContainerPath, message, null); 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 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 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) { writer.WritePropertyName(JsonTypeReflector.IdPropertyName); writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, value)); } if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract, containerProperty)) { WriteTypeProperty(writer, contract.UnderlyingType); } }
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) { writer.WriteValue(value); } 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; SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionValueContract); } else if (valueContract is JsonLinqContract) { ((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null); } #if !SILVERLIGHT && !PocketPC else if (valueContract is JsonISerializableContract) { SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract); } #endif #if !(NET35 || NET20 || WINDOWS_PHONE) else if (valueContract is JsonDynamicContract) { SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract); } #endif }
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 && containerContract.ItemContract != null) { if (contract.UnderlyingType != containerContract.ItemContract.CreatedType) return true; } } return false; }
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.DictionaryKeyResolver != null) ? contract.DictionaryKeyResolver(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 bool ReadForType(JsonReader reader, JsonContract contract, bool hasConverter, bool inArray) { // don't read properties with converters as a specific value // the value might be a string which will then get converted which will error if read as date for example if (hasConverter) return reader.Read(); ReadType t = (contract != null) ? contract.InternalReadType : ReadType.Read; switch (t) { case ReadType.Read: do { if (!reader.Read()) return false; } while (reader.TokenType == JsonToken.Comment); return true; case ReadType.ReadAsInt32: reader.ReadAsInt32(); break; case ReadType.ReadAsDecimal: reader.ReadAsDecimal(); break; case ReadType.ReadAsBytes: reader.ReadAsBytes(); break; case ReadType.ReadAsString: reader.ReadAsString(); break; case ReadType.ReadAsDateTime: reader.ReadAsDateTime(); break; #if !NET20 case ReadType.ReadAsDateTimeOffset: reader.ReadAsDateTimeOffset(); break; #endif default: throw new ArgumentOutOfRangeException(); } return (reader.TokenType != JsonToken.None); }
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) { if (value == null) { writer.WriteNull(); return; } JsonConverter converter = ((member != null) ? member.Converter : null) ?? ((containerProperty != null) ? containerProperty.ItemConverter : null) ?? ((containerContract != null) ? containerContract.ItemConverter : null) ?? valueContract.Converter ?? Serializer.GetMatchingConverter(valueContract.UnderlyingType) ?? valueContract.InternalConverter; if (converter != 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; #if !(NET35 || NET20 || PORTABLE40) case JsonContractType.Dynamic: SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty); break; #endif #if !(DOTNET || PORTABLE40 || PORTABLE) case JsonContractType.Serializable: SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, containerContract, containerProperty); break; #endif case JsonContractType.Linq: ((JToken)value).WriteTo(writer, Serializer.Converters.ToArray()); break; } }
private object CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract, JsonConverter converter) { if (converter != null && converter.CanRead) return converter.ReadJson(reader, objectType, null, GetInternalSerializer()); return CreateValueInternal(reader, objectType, contract, null, null); }
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; } bool exists = (Serializer._equalityComparer != null) ? _serializeStack.Contains(value, Serializer._equalityComparer) : _serializeStack.Contains(value); if (exists) { 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()); switch (referenceLoopHandling.GetValueOrDefault(Serializer._referenceLoopHandling)) { 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 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 void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { OnSerializing(writer, contract, value); _serializeStack.Add(value); WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); int initialDepth = writer.Top; for (int index = 0; index < contract.Properties.Count; index++) { JsonProperty property = contract.Properties[index]; try { object memberValue; JsonContract memberContract; if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) { continue; } property.WritePropertyName(writer); SerializeValue(writer, memberValue, memberContract, property, contract, member); } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } } if (contract.ExtensionDataGetter != null) { IEnumerable <KeyValuePair <object, object> > extensionData = contract.ExtensionDataGetter(value); if (extensionData != null) { foreach (KeyValuePair <object, object> e in extensionData) { JsonContract keyContract = GetContractSafe(e.Key); JsonContract valueContract = GetContractSafe(e.Value); bool escape; string propertyName = GetPropertyName(writer, e.Key, keyContract, out escape); if (ShouldWriteReference(e.Value, null, valueContract, contract, member)) { writer.WritePropertyName(propertyName); WriteReference(writer, e.Value); } else { if (!CheckForCircularReference(writer, e.Value, null, valueContract, contract, member)) { continue; } writer.WritePropertyName(propertyName); SerializeValue(writer, e.Value, valueContract, null, contract, member); } } } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, value); }
private JsonArrayContract EnsureArrayContract(JsonReader reader, Type objectType, JsonContract contract) { if (contract == null) throw CreateSerializationException(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); JsonArrayContract arrayContract = contract as JsonArrayContract; if (arrayContract == null) throw CreateSerializationException(reader, @"Cannot deserialize JSON array (i.e. [1,2,3]) into type '{0}'. The deserialized type must be an array or implement a collection interface like IEnumerable, ICollection or IList. To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".FormatWith(CultureInfo.InvariantCulture, objectType)); return arrayContract; }
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); } if (resolvedRequired == Required.DisallowNull) { throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a non-null value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null); } } return(true); } } memberContract = null; memberValue = null; return(false); }
private object EnsureType(JsonReader reader, object value, CultureInfo culture, JsonContract contract, Type targetType) { if (targetType == null) return value; Type valueType = ReflectionUtils.GetObjectType(value); // type of value and type of target don't match // attempt to convert value's type to target's type if (valueType != targetType) { try { if (value == null && contract.IsNullable) return null; if (contract.IsConvertable) { if (contract.NonNullableUnderlyingType.IsEnum()) { if (value is string) return Enum.Parse(contract.NonNullableUnderlyingType, value.ToString(), true); else if (ConvertUtils.IsInteger(value)) return Enum.ToObject(contract.NonNullableUnderlyingType, value); } return Convert.ChangeType(value, contract.NonNullableUnderlyingType, culture); } return ConvertUtils.ConvertOrCast(value, culture, contract.NonNullableUnderlyingType); } catch (Exception ex) { throw CreateSerializationException(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, FormatValueForPrint(value), targetType), ex); } } return value; }
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); } }