Beispiel #1
0
        private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context);

            _serializeStack.Add(values.UnderlyingDictionary);

            WriteObjectStart(writer, values.UnderlyingDictionary, contract, member, collectionContract, collectionValueContract);

            if (contract.DictionaryValueContract == null)
            {
                contract.DictionaryValueContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object));
            }

            JsonContract dictionaryValueContract = (contract.DictionaryValueContract.UnderlyingType.IsSealed()) ? contract.DictionaryValueContract : null;

            int initialDepth = writer.Top;

            // Mono Unity 3.0 fix
            IWrappedDictionary 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 = dictionaryValueContract ?? GetContractSafe(value);

                    if (ShouldWriteReference(value, null, valueContract, contract))
                    {
                        writer.WritePropertyName(propertyName);
                        WriteReference(writer, value);
                    }
                    else
                    {
                        if (!CheckForCircularReference(value, null, valueContract, contract))
                        {
                            continue;
                        }

                        writer.WritePropertyName(propertyName);

                        SerializeValue(writer, value, valueContract, null, contract, dictionaryValueContract);
                    }
                }
                catch (Exception ex)
                {
                    if (IsErrorHandled(values.UnderlyingDictionary, contract, propertyName, writer.ContainerPath, ex))
                    {
                        HandleError(writer, initialDepth);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            writer.WriteEndObject();

            _serializeStack.RemoveAt(_serializeStack.Count - 1);

            contract.InvokeOnSerialized(values.UnderlyingDictionary, Serializer.Context);
        }
Beispiel #2
0
        private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            if (contract.UnderlyingType == typeof(byte[]))
            {
                bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract, collectionValueContract);
                if (includeTypeDetails)
                {
                    writer.WriteStartObject();
                    WriteTypeProperty(writer, contract.CreatedType);
                    writer.WritePropertyName(JsonTypeReflector.ValuePropertyName);
                    writer.WriteValue(value);
                    writer.WriteEndObject();
                    return;
                }
            }

            writer.WriteValue(value);
        }
Beispiel #3
0
        private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            contract.InvokeOnSerializing(value, Serializer.Context);
            _serializeStack.Add(value);

            WriteObjectStart(writer, value, contract, member, collectionContract, collectionValueContract);

            foreach (string memberName in value.GetDynamicMemberNames())
            {
                object memberValue;
                if (DynamicUtils.TryGetMember(value, memberName, out memberValue))
                {
                    string resolvedPropertyName = (contract.PropertyNameResolver != null)
                                          ? contract.PropertyNameResolver(memberName)
                                          : memberName;

                    writer.WritePropertyName(resolvedPropertyName);
                    SerializeValue(writer, memberValue, GetContractSafe(memberValue), null, null, null);
                }
            }

            writer.WriteEndObject();

            _serializeStack.RemoveAt(_serializeStack.Count - 1);
            contract.InvokeOnSerialized(value, Serializer.Context);
        }
Beispiel #4
0
        private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            TypeNameHandling resolvedTypeNameHandling = ((member != null) ? member.TypeNameHandling : null)
                                                        ?? ((collectionContract != null) ? collectionContract.ItemTypeNameHandling : null)
                                                        ?? Serializer.TypeNameHandling;

            if (HasFlag(resolvedTypeNameHandling, 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);
        }
Beispiel #5
0
        private bool WriteStartArray(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            bool isReference         = ResolveIsReference(contract, member, collectionContract) ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
            bool includeTypeDetails  = ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionContract, collectionValueContract);
            bool writeMetadataObject = isReference || includeTypeDetails;

            if (writeMetadataObject)
            {
                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);
            }

            if (contract.CollectionItemContract == null)
            {
                contract.CollectionItemContract = Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object));
            }

            return(writeMetadataObject);
        }
Beispiel #6
0
        private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            if (!JsonTypeReflector.FullyTrusted)
            {
                throw new JsonSerializationException(@"Type '{0}' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add to JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
            }

            contract.InvokeOnSerializing(value, Serializer.Context);
            _serializeStack.Add(value);

            WriteObjectStart(writer, value, contract, member, collectionContract, collectionValueContract);

            SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter());

            value.GetObjectData(serializationInfo, Serializer.Context);

            foreach (SerializationEntry serializationEntry in serializationInfo)
            {
                writer.WritePropertyName(serializationEntry.Name);
                SerializeValue(writer, serializationEntry.Value, GetContractSafe(serializationEntry.Value), null, null, null);
            }

            writer.WriteEndObject();

            _serializeStack.RemoveAt(_serializeStack.Count - 1);
            contract.InvokeOnSerialized(value, Serializer.Context);
        }
Beispiel #7
0
        private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            if (ShouldWriteReference(value, null, contract, collectionContract))
            {
                WriteReference(writer, value);
            }
            else
            {
                if (!CheckForCircularReference(value, null, contract, collectionContract))
                {
                    return;
                }

                _serializeStack.Add(value);

                converter.WriteJson(writer, value, GetInternalSerializer());

                _serializeStack.RemoveAt(_serializeStack.Count - 1);
            }
        }
Beispiel #8
0
        private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            contract.InvokeOnSerializing(values.UnderlyingCollection, Serializer.Context);

            _serializeStack.Add(values.UnderlyingCollection);

            bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract, collectionValueContract);

            writer.WriteStartArray();

            JsonContract collectionItemValueContract = (contract.CollectionItemContract.UnderlyingType.IsSealed()) ? contract.CollectionItemContract : null;

            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 = collectionItemValueContract ?? GetContractSafe(value);

                    if (ShouldWriteReference(value, null, valueContract, contract))
                    {
                        WriteReference(writer, value);
                    }
                    else
                    {
                        if (CheckForCircularReference(value, null, valueContract, contract))
                        {
                            SerializeValue(writer, value, valueContract, null, contract, contract.CollectionItemContract);
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (IsErrorHandled(values.UnderlyingCollection, contract, index, writer.ContainerPath, ex))
                    {
                        HandleError(writer, initialDepth);
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    index++;
                }
            }

            writer.WriteEndArray();

            if (hasWrittenMetadataObject)
            {
                writer.WriteEndObject();
            }

            _serializeStack.RemoveAt(_serializeStack.Count - 1);

            contract.InvokeOnSerialized(values.UnderlyingCollection, Serializer.Context);
        }
Beispiel #9
0
        private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            contract.InvokeOnSerializing(value, Serializer.Context);

            _serializeStack.Add(value);

            WriteObjectStart(writer, value, contract, member, collectionContract, collectionValueContract);

            int initialDepth = writer.Top;

            foreach (JsonProperty property in contract.Properties)
            {
                try
                {
                    if (!property.Ignored && property.Readable && ShouldSerialize(property, value) && IsSpecified(property, value))
                    {
                        if (property.PropertyContract == null)
                        {
                            property.PropertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType);
                        }

                        object       memberValue    = property.ValueProvider.GetValue(value);
                        JsonContract memberContract = (property.PropertyContract.UnderlyingType.IsSealed()) ? property.PropertyContract : GetContractSafe(memberValue);

                        if (ShouldWriteProperty(memberValue, property))
                        {
                            WriteMemberInfoProperty(writer, memberValue, property, memberContract, contract);
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (IsErrorHandled(value, contract, property.PropertyName, writer.ContainerPath, ex))
                    {
                        HandleError(writer, initialDepth);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            writer.WriteEndObject();

            _serializeStack.RemoveAt(_serializeStack.Count - 1);

            contract.InvokeOnSerialized(value, Serializer.Context);
        }
Beispiel #10
0
        private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            writer.WriteStartObject();

            bool isReference = ResolveIsReference(contract, member, collectionContract) ?? 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, collectionValueContract))
            {
                WriteTypeProperty(writer, contract.UnderlyingType);
            }
        }
Beispiel #11
0
        private bool CheckForCircularReference(object value, JsonProperty property, JsonContract contract, JsonContainerContract collectionContract)
        {
            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 && collectionContract != null)
            {
                referenceLoopHandling = collectionContract.ItemReferenceLoopHandling;
            }

            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);
        }
Beispiel #12
0
        private void WriteMemberInfoProperty(JsonWriter writer, object memberValue, JsonProperty property, JsonContract contract, JsonContainerContract collectionContract)
        {
            string propertyName = property.PropertyName;

            if (ShouldWriteReference(memberValue, property, contract, collectionContract))
            {
                writer.WritePropertyName(propertyName);
                WriteReference(writer, memberValue);
                return;
            }

            if (!CheckForCircularReference(memberValue, property, contract, collectionContract))
            {
                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, collectionContract, null);
        }
Beispiel #13
0
        private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract)
        {
            if (value == null)
            {
                return(false);
            }
            if (valueContract.ContractType == JsonContractType.Primitive || valueContract.ContractType == JsonContractType.String)
            {
                return(false);
            }

            bool?isReference = ResolveIsReference(valueContract, property, collectionContract);

            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));
        }
Beispiel #14
0
        private bool?ResolveIsReference(JsonContract contract, JsonProperty property, JsonContainerContract collectionContract)
        {
            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 && collectionContract != null)
            {
                isReference = collectionContract.ItemIsReference;
            }

            if (isReference == null)
            {
                isReference = contract.IsReference;
            }

            return(isReference);
        }
Beispiel #15
0
        private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract collectionContract, JsonContract collectionValueContract)
        {
            if (value == null)
            {
                writer.WriteNull();
                return;
            }

            JsonConverter converter;

            if ((((converter = (member != null) ? member.Converter : null) != null) ||
                 ((converter = (collectionContract != null) ? collectionContract.ItemConverter : null) != null) ||
                 ((converter = valueContract.Converter) != null) ||
                 ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null) ||
                 ((converter = valueContract.InternalConverter) != null)) &&
                converter.CanWrite)
            {
                SerializeConvertable(writer, converter, value, valueContract, collectionContract, collectionValueContract);
                return;
            }

            switch (valueContract.ContractType)
            {
            case JsonContractType.Object:
                SerializeObject(writer, value, (JsonObjectContract)valueContract, member, collectionContract, collectionValueContract);
                break;

            case JsonContractType.Array:
                JsonArrayContract arrayContract = (JsonArrayContract)valueContract;
                SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionContract, collectionValueContract);
                break;

            case JsonContractType.Primitive:
                SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, collectionContract, collectionValueContract);
                break;

            case JsonContractType.String:
                SerializeString(writer, value, (JsonStringContract)valueContract);
                break;

            case JsonContractType.Dictionary:
                JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)valueContract;
                SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionContract, collectionValueContract);
                break;

#if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
            case JsonContractType.Dynamic:
                SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, collectionContract, collectionValueContract);
                break;
#endif
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
            case JsonContractType.Serializable:
                SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, collectionContract, collectionValueContract);
                break;
#endif
            case JsonContractType.Linq:
                ((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
                break;
            }
        }