示例#1
0
    /// <summary>
    /// Writes the current <see cref="JsonReader"/> token.
    /// </summary>
    /// <param name="reader">The <see cref="JsonReader"/> to read the token from.</param>
    public void WriteToken(JsonReader reader)
    {
      ValidationUtils.ArgumentNotNull(reader, "reader");

      int currentDepth;

      if (reader.TokenType == JsonToken.None)
        currentDepth = -1;
      else if (!IsStartToken(reader.TokenType))
        currentDepth = reader.Depth + 1;
      else
        currentDepth = reader.Depth;

      do
      {
        switch (reader.TokenType)
        {
          case JsonToken.None:
            // read to next
            break;
          case JsonToken.StartObject:
            WriteStartObject();
            break;
          case JsonToken.StartArray:
            WriteStartArray();
            break;
          case JsonToken.StartConstructor:
            string constructorName = reader.Value.ToString();
            // write a JValue date when the constructor is for a date
            if (string.Compare(constructorName, "Date", StringComparison.Ordinal) == 0)
              WriteConstructorDate(reader);
            else
              WriteStartConstructor(reader.Value.ToString());
            break;
          case JsonToken.PropertyName:
            WritePropertyName(reader.Value.ToString());
            break;
          case JsonToken.Comment:
            WriteComment(reader.Value.ToString());
            break;
          case JsonToken.Integer:
            WriteValue((long)reader.Value);
            break;
          case JsonToken.Float:
            WriteValue((double)reader.Value);
            break;
          case JsonToken.String:
            WriteValue(reader.Value.ToString());
            break;
          case JsonToken.Boolean:
            WriteValue((bool)reader.Value);
            break;
          case JsonToken.Null:
            WriteNull();
            break;
          case JsonToken.Undefined:
            WriteUndefined();
            break;
          case JsonToken.EndObject:
            WriteEndObject();
            break;
          case JsonToken.EndArray:
            WriteEndArray();
            break;
          case JsonToken.EndConstructor:
            WriteEndConstructor();
            break;
          case JsonToken.Date:
            WriteValue((DateTime)reader.Value);
            break;
          case JsonToken.Raw:
            WriteRawValue((string)reader.Value);
            break;
          default:
            throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type.");
        }
      }
      while (
        // stop if we have reached the end of the token being read
        currentDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0)
        && reader.Read());
    }
示例#2
0
    private void WriteConstructorDate(JsonReader reader)
    {
      if (!reader.Read())
        throw new Exception("Unexpected end while reading date constructor.");
      if (reader.TokenType != JsonToken.Integer)
        throw new Exception("Unexpected token while reading date constructor. Expected Integer, got " + reader.TokenType);

      long ticks = (long)reader.Value;
      DateTime date = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);

      if (!reader.Read())
        throw new Exception("Unexpected end while reading date constructor.");
      if (reader.TokenType != JsonToken.EndConstructor)
        throw new Exception("Unexpected token while reading date constructor. Expected EndConstructor, got " + reader.TokenType);

      WriteValue(date);
    }
示例#3
0
    private object CreateObjectFromNonDefaultConstructor(Type objectType, JsonReader reader)
    {
      // object should have a single constructor
      ConstructorInfo c = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).SingleOrDefault();

      if (c == null)
        throw new JsonSerializationException("Could not find a public constructor for type {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));

      // create a dictionary to put retrieved values into
      JsonMemberMappingCollection memberMappings = GetMemberMappings(objectType);
      IDictionary<JsonMemberMapping, object> mappingValues = memberMappings.ToDictionary(kv => kv, kv => (object)null);

      bool exit = false;
      while (!exit && reader.Read())
      {
        switch (reader.TokenType)
        {
          case JsonToken.PropertyName:
            string memberName = reader.Value.ToString();
            if (!reader.Read())
              throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

            JsonMemberMapping memberMapping;
            // attempt exact case match first
            // then try match ignoring case
            if (memberMappings.TryGetClosestMatchMapping(memberName, out memberMapping))
            {
              if (!memberMapping.Ignored)
              {
                Type memberType = ReflectionUtils.GetMemberUnderlyingType(memberMapping.Member);
                mappingValues[memberMapping] = CreateObject(reader, memberType, null, memberMapping.MemberConverter);
              }
            }
            else
            {
              if (_missingMemberHandling == MissingMemberHandling.Error)
                throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));

              reader.Skip();
            }
            break;
          case JsonToken.EndObject:
            exit = true;
            break;
          default:
            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
        }
      }

      IDictionary<ParameterInfo, object> constructorParameters = c.GetParameters().ToDictionary(p => p, p => (object)null);
      IDictionary<JsonMemberMapping, object> remainingMappingValues = new Dictionary<JsonMemberMapping, object>();

      foreach (KeyValuePair<JsonMemberMapping, object> mappingValue in mappingValues)
      {
        ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, mappingValue.Key.MappingName).Key;
        if (matchingConstructorParameter != null)
          constructorParameters[matchingConstructorParameter] = mappingValue.Value;
        else
          remainingMappingValues.Add(mappingValue);
      }

      object createdObject = ReflectionUtils.CreateInstance(objectType, constructorParameters.Values.ToArray());

      // go through unused values and set the newly created object's properties
      foreach (KeyValuePair<JsonMemberMapping, object> remainingMappingValue in remainingMappingValues)
      {
        if (ShouldSetMappingValue(remainingMappingValue.Key, remainingMappingValue.Value))
          ReflectionUtils.SetMemberValue(remainingMappingValue.Key.Member, createdObject, remainingMappingValue.Value);
      }

      return createdObject;
    }
示例#4
0
    private object PopulateObject(object newObject, JsonReader reader, Type objectType)
    {
      JsonMemberMappingCollection memberMappings = GetMemberMappings(objectType);
      Dictionary<string, bool> requiredMappings =
        memberMappings.Where(m => m.Required).ToDictionary(m => m.MappingName, m => false);

      while (reader.Read())
      {
        switch (reader.TokenType)
        {
          case JsonToken.PropertyName:
            string memberName = reader.Value.ToString();

            if (!reader.Read())
              throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

            if (reader.TokenType != JsonToken.Null)
              SetRequiredMapping(memberName, requiredMappings);

            SetObjectMember(reader, newObject, objectType, memberName);
            break;
          case JsonToken.EndObject:
            foreach (KeyValuePair<string, bool> requiredMapping in requiredMappings)
            {
              if (!requiredMapping.Value)
                throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredMapping.Key));
            }
            return newObject;
          default:
            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
        }
      }

      throw new JsonSerializationException("Unexpected end when deserializing object.");
    }
示例#5
0
    private IList PopulateList(IList list, Type listItemType, JsonReader reader)
    {
      while (reader.Read())
      {
        switch (reader.TokenType)
        {
          case JsonToken.EndArray:
            return list;
          case JsonToken.Comment:
            break;
          default:
            object value = CreateObject(reader, listItemType, null, null);

            list.Add(value);
            break;
        }
      }

      throw new JsonSerializationException("Unexpected end when deserializing array.");
    }
示例#6
0
    private object CreateAndPopulateObject(JsonReader reader, Type objectType)
    {
      object newObject;

      if (objectType.IsInterface || objectType.IsAbstract)
        throw new JsonSerializationException("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, objectType));
      
      if (ReflectionUtils.HasDefaultConstructor(objectType))
      {
        newObject = Activator.CreateInstance(objectType);

        PopulateObject(newObject, reader, objectType);
        return newObject;
      }
      
      return CreateObjectFromNonDefaultConstructor(objectType, reader);
    }
示例#7
0
    private IDictionary PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader)
    {
      Type dictionaryType = dictionary.UnderlyingDictionary.GetType();
      Type dictionaryKeyType = ReflectionUtils.GetDictionaryKeyType(dictionaryType);
      Type dictionaryValueType = ReflectionUtils.GetDictionaryValueType(dictionaryType);

      while (reader.Read())
      {
        switch (reader.TokenType)
        {
          case JsonToken.PropertyName:
            object keyValue = EnsureType(reader.Value, dictionaryKeyType);
            reader.Read();

            dictionary.Add(keyValue, CreateObject(reader, dictionaryValueType, null, null));
            break;
          case JsonToken.EndObject:
            return dictionary;
          default:
            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
        }
      }

      throw new JsonSerializationException("Unexpected end when deserializing object.");
    }
示例#8
0
    /// <summary>
    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
    /// into an instance of the specified type.
    /// </summary>
    /// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
    /// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
    /// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
    public object Deserialize(JsonReader reader, Type objectType)
    {
      if (reader == null)
        throw new ArgumentNullException("reader");

      if (!reader.Read())
        return null;

      if (objectType != null)
        return CreateObject(reader, objectType, null, null);
      else
        return CreateJToken(reader);
    }
示例#9
0
    private void SetMappingValue(JsonMemberMapping memberMapping, JsonReader reader, object target)
    {
      if (memberMapping.Ignored)
      {
        reader.Skip();
        return;
      }

      // get the member's underlying type
      Type memberType = ReflectionUtils.GetMemberUnderlyingType(memberMapping.Member);

      object currentValue = null;
      bool useExistingValue = false;

      if ((_objectCreationHandling == ObjectCreationHandling.Auto || _objectCreationHandling == ObjectCreationHandling.Reuse)
          && (reader.TokenType == JsonToken.StartArray || reader.TokenType == JsonToken.StartObject))
      {
        currentValue = ReflectionUtils.GetMemberValue(memberMapping.Member, target);

        useExistingValue = (currentValue != null && !memberType.IsArray && !ReflectionUtils.InheritsGenericDefinition(memberType, typeof(ReadOnlyCollection<>)));
      }

      if (!memberMapping.Writable && !useExistingValue)
      {
        reader.Skip();
        return;
      }

      object value = CreateObject(reader, memberType, (useExistingValue) ? currentValue : null, JsonTypeReflector.GetConverter(memberMapping.Member, memberType));

      if (!useExistingValue && ShouldSetMappingValue(memberMapping, value))
        ReflectionUtils.SetMemberValue(memberMapping.Member, target, value);
    }
示例#10
0
    private object CreateAndPopulateDictionary(JsonReader reader, Type objectType)
    {
      if (IsTypeGenericDictionaryInterface(objectType))
      {
        Type keyType;
        Type valueType;
        ReflectionUtils.GetDictionaryKeyValueTypes(objectType, out keyType, out valueType);
        objectType = ReflectionUtils.MakeGenericType(typeof(Dictionary<,>), keyType, valueType);
      }

      IWrappedDictionary dictionary = CollectionUtils.CreateDictionaryWrapper(Activator.CreateInstance(objectType));
      PopulateDictionary(dictionary, reader);

      return dictionary.UnderlyingDictionary;
    }
示例#11
0
    private void SetObjectMember(JsonReader reader, object target, Type targetType, string memberName)
    {
      JsonMemberMappingCollection memberMappings = GetMemberMappings(targetType);

      JsonMemberMapping memberMapping;
      // attempt exact case match first
      // then try match ignoring case
      if (memberMappings.TryGetClosestMatchMapping(memberName, out memberMapping))
      {
        SetMappingValue(memberMapping, reader, target);
      }
      else
      {
        if (_missingMemberHandling == MissingMemberHandling.Error)
          throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, targetType.Name));

        reader.Skip();
      }
    }
示例#12
0
    private object CreateObject(JsonReader reader, Type objectType, object existingValue, JsonConverter memberConverter)
    {
      _level++;

      object value;
      JsonConverter converter;

      if (memberConverter != null)
      {
        return memberConverter.ReadJson(reader, objectType);
      }
      else if (objectType != null && HasClassConverter(objectType, out converter))
      {
        return converter.ReadJson(reader, objectType);
      }
      else if (objectType != null && HasMatchingConverter(objectType, out converter))
      {
        return converter.ReadJson(reader, objectType);
      }
      else if (objectType == typeof(JsonRaw))
      {
        return JsonRaw.Create(reader);
      }
      else
      {
        switch (reader.TokenType)
        {
          // populate a typed object or generic dictionary/array
          // depending upon whether an objectType was supplied
          case JsonToken.StartObject:
            if (objectType == null)
            {
              value = CreateJToken(reader);
            }
            else if (CollectionUtils.IsDictionaryType(objectType))
            {
              if (existingValue == null)
                value = CreateAndPopulateDictionary(reader, objectType);
              else
                value = PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(existingValue), reader);
            }
            else
            {
              if (existingValue == null)
                value = CreateAndPopulateObject(reader, objectType);
              else
                value = PopulateObject(existingValue, reader, objectType);
            }
            break;
          case JsonToken.StartArray:
            if (objectType != null)
            {
              if (existingValue == null)
                value = CreateAndPopulateList(reader, objectType);
              else
                value = PopulateList(CollectionUtils.CreateCollectionWrapper(existingValue), ReflectionUtils.GetCollectionItemType(objectType), reader);
            }
            else
            {
              value = CreateJToken(reader);
            }
            break;
          case JsonToken.Integer:
          case JsonToken.Float:
          case JsonToken.String:
          case JsonToken.Boolean:
          case JsonToken.Date:
            value = EnsureType(reader.Value, objectType);
            break;
          case JsonToken.StartConstructor:
          case JsonToken.EndConstructor:
            string constructorName = reader.Value.ToString();

            value = constructorName;
            break;
          case JsonToken.Null:
          case JsonToken.Undefined:
            if (objectType == typeof(DBNull))
              value = DBNull.Value;
            else
              value = null;
            break;
          default:
            throw new JsonSerializationException("Unexpected token while deserializing object: " + reader.TokenType);
        }
      }

      _level--;

      return value;
    }
示例#13
0
    private JToken CreateJToken(JsonReader reader)
    {
      JToken token;
      using (JsonTokenWriter writer = new JsonTokenWriter())
      {
        writer.WriteToken(reader);
        token = writer.Token;
      }

      return token;
    }
示例#14
0
 /// <summary>
 /// Reads the JSON representation of the object.
 /// </summary>
 /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
 /// <param name="objectType">Type of the object.</param>
 /// <returns>The object value.</returns>
 public abstract object ReadJson(JsonReader reader, Type objectType);
示例#15
0
    private object CreateAndPopulateList(JsonReader reader, Type objectType)
    {
      if (IsTypeGenericCollectionInterface(objectType))
      {
        Type itemType = ReflectionUtils.GetCollectionItemType(objectType);
        objectType = ReflectionUtils.MakeGenericType(typeof(List<>), itemType);
      }

      return CollectionUtils.CreateAndPopulateList(objectType, l => PopulateList(l, ReflectionUtils.GetCollectionItemType(objectType), reader));
    }
示例#16
0
    /// <summary>
    /// Creates an instance of <see cref="JsonRaw"/> with the content of the reader's current token.
    /// </summary>
    /// <param name="reader">The reader.</param>
    /// <returns>An instance of <see cref="JsonRaw"/> with the content of the reader's current token.</returns>
    public static JsonRaw Create(JsonReader reader)
    {
      using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
      {
        jsonWriter.WriteToken(reader);

        return new JsonRaw(sw.ToString());
      }
    }
示例#17
0
 /// <summary>
 /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>.
 /// </summary>
 /// <param name="reader">The <see cref="JsonReader"/> that contains the Json structure to deserialize.</param>
 /// <returns>The <see cref="Object"/> being deserialized.</returns>
 public object Deserialize(JsonReader reader)
 {
   return Deserialize(reader, null);
 }