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

            if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore &&
                memberValue == null)
            {
                return;
            }

            if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore) &&
                MiscellaneousUtils.ValueEquals(memberValue, defaultValue))
            {
                return;
            }

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

            if (!CheckForCircularReference(memberValue, property.ReferenceLoopHandling, contract))
            {
                return;
            }

            if (memberValue == null && property.Required == Required.Always)
            {
                throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
            }

            writer.WritePropertyName(propertyName);
            SerializeValue(writer, memberValue, contract, property, null);
        }
    private 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 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))
          {
            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);

            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 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);
      }

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

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

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

          if (ShouldWriteReference(value, null, valueContract))
          {
            WriteReference(writer, value);
          }
          else
          {
            if (CheckForCircularReference(value, null, contract))
            {
              SerializeValue(writer, value, valueContract, null, contract.CollectionItemContract);
            }
          }
        }
        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 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();
              return true;
            case ReadType.ReadAsDecimal:
              reader.ReadAsDecimal();
              return true;
            case ReadType.ReadAsBytes:
              reader.ReadAsBytes();
              return true;
            #if !NET20
            case ReadType.ReadAsDateTimeOffset:
              reader.ReadAsDateTimeOffset();
              return true;
            #endif
            default:
              throw new ArgumentOutOfRangeException();
              }
        }
    private void WriteMemberInfoProperty(JsonWriter writer, object memberValue, JsonProperty property, JsonContract contract)
    {
      string propertyName = property.PropertyName;
      object defaultValue = property.DefaultValue;

      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore &&
          memberValue == null)
        return;

      if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore)
        && MiscellaneousUtils.ValueEquals(memberValue, defaultValue))
        return;

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

      if (!CheckForCircularReference(memberValue, property.ReferenceLoopHandling, contract))
        return;

      if (memberValue == null && property.Required == Required.Always)
        throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));

      writer.WritePropertyName(propertyName);
      SerializeValue(writer, memberValue, contract, property, null);
    }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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());
            }

            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
            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 = dictionaryValueContract ?? 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, contract.DictionaryValueContract);
                    }
                }
                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);
        }
Beispiel #10
0
        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);
            }

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

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

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

                    if (ShouldWriteReference(value, null, valueContract))
                    {
                        WriteReference(writer, value);
                    }
                    else
                    {
                        if (CheckForCircularReference(value, null, contract))
                        {
                            SerializeValue(writer, value, valueContract, null, contract.CollectionItemContract);
                        }
                    }
                }
                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);
        }
Beispiel #11
0
        private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContract collectionValueContract)
        {
            contract.InvokeOnSerializing(value, Serializer.Context);
            _serializeStack.Add(value);

            writer.WriteStartObject();

            if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract))
            {
                WriteTypeProperty(writer, contract.UnderlyingType);
            }

            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);
            }

            writer.WriteEndObject();

            _serializeStack.RemoveAt(_serializeStack.Count - 1);
            contract.InvokeOnSerialized(value, Serializer.Context);
        }
Beispiel #12
0
        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);
            }
        }
Beispiel #13
0
        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))
                    {
                        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);

                        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);
        }
Beispiel #14
0
        private bool CheckForCircularReference(object value, ReferenceLoopHandling?referenceLoopHandling, JsonContract contract)
        {
            if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
            {
                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 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 System.Enum.Parse(contract.NonNullableUnderlyingType, value.ToString(), true);
                else if (ConvertUtils.IsInteger(value))
                  return System.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;
        }
Beispiel #16
0
        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 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 JToken CreateJToken(JsonReader reader, JsonContract contract)
        {
            ValidationUtils.ArgumentNotNull(reader, "reader");

              if (contract != null && contract.UnderlyingType == typeof (JRaw))
              {
            return JRaw.Create(reader);
              }
              else
              {
            JToken token;
            using (JTokenWriter writer = new JTokenWriter())
            {
              writer.WriteToken(reader);
              token = writer.Token;
            }

            return token;
              }
        }
    private bool ShouldWriteReference(object value, JsonProperty property, JsonContract contract)
    {
      if (value == null)
        return false;
      if (contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
        return false;

      bool? isReference = null;

      // value could be coming from a dictionary or array and not have a property
      if (property != null)
        isReference = property.IsReference;

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

      if (isReference == null)
      {
        if (contract.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 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 CheckForCircularReference(object value, ReferenceLoopHandling? referenceLoopHandling, JsonContract contract)
    {
      if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
        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 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
            case JsonContractType.Serializable:
              JsonISerializableContract serializableContract = (JsonISerializableContract) contract;
              return CreateISerializable(reader, serializableContract, id);
            #endif
              }

              throw CreateSerializationException(reader, "Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
        }
    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 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 (objectType == typeof (DBNull))
              return DBNull.Value;

            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 SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContract collectionValueContract)
    {
      contract.InvokeOnSerializing(value, Serializer.Context);
      _serializeStack.Add(value);

      writer.WriteStartObject();

      if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract))
      {
          WriteTypeProperty(writer, contract.UnderlyingType);
      }

      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);
      }

      writer.WriteEndObject();

      _serializeStack.RemoveAt(_serializeStack.Count - 1);
      contract.InvokeOnSerialized(value, Serializer.Context);
    }
        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 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());
      }

      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
      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 = dictionaryValueContract ?? 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, contract.DictionaryValueContract);
          }
        }
        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 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 into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));

              return arrayContract;
        }
    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);
        return;
      }

      switch (valueContract.ContractType)
      {
        case JsonContractType.Object:
          SerializeObject(writer, value, (JsonObjectContract) valueContract, member, collectionValueContract);
          break;
        case JsonContractType.Array:
          JsonArrayContract arrayContract = (JsonArrayContract) valueContract;
          SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionValueContract);
          break;
        case JsonContractType.Primitive:
          SerializePrimitive(writer, value, (JsonPrimitiveContract) valueContract, member, 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, collectionValueContract);
          break;
#if !(NET35 || NET20 || WINDOWS_PHONE)
        case JsonContractType.Dynamic:
          SerializeDynamic(writer, (IDynamicMetaObjectProvider) value, (JsonDynamicContract) valueContract);
          break;
#endif
#if !SILVERLIGHT && !PocketPC
        case JsonContractType.Serializable:
          SerializeISerializable(writer, (ISerializable) value, (JsonISerializableContract) valueContract, member, collectionValueContract);
          break;
#endif
        case JsonContractType.Linq:
          ((JToken) value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
          break;
      }
    }
Beispiel #30
0
        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);
                return;
            }

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

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

            case JsonContractType.Primitive:
                SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, 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, collectionValueContract);
                break;

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