Exemplo n.º 1
0
        private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context);

            _serializeStack.Add(values.UnderlyingDictionary);

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

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

            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 = contract.FinalItemContract ?? GetContractSafe(value);

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

                        writer.WritePropertyName(propertyName);

                        SerializeValue(writer, value, valueContract, null, contract, member);
                    }
                }
                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);
        }
Exemplo n.º 2
0
        private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            contract.InvokeOnSerializing(values.UnderlyingCollection, Serializer.Context);

            _serializeStack.Add(values.UnderlyingCollection);

            bool hasWrittenMetadataObject = WriteStartArray(writer, values, 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(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);
        }
Exemplo n.º 3
0
        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);
            }
        }
Exemplo n.º 4
0
        private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            contract.InvokeOnSerializing(value, Serializer.Context);

            _serializeStack.Add(value);

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

            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))
                        {
                            string propertyName = property.PropertyName;

                            if (ShouldWriteReference(memberValue, property, memberContract, contract, member))
                            {
                                writer.WritePropertyName(propertyName);
                                WriteReference(writer, memberValue);
                                continue;
                            }

                            if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member))
                            {
                                continue;
                            }

                            if (memberValue == null)
                            {
                                Required resolvedRequired = property._required ?? contract.ItemRequired ?? 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);
                                }
                            }

                            writer.WritePropertyName(propertyName);
                            SerializeValue(writer, memberValue, memberContract, property, contract, member);
                        }
                    }
                }
                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);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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;
                SerializeList(writer, arrayContract.CreateWrapper(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;
            }
        }