Ejemplo n.º 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());
    }
Ejemplo n.º 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);
    }
Ejemplo n.º 3
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.");
    }
Ejemplo n.º 4
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;
    }
Ejemplo n.º 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.");
    }
Ejemplo n.º 6
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.");
    }
Ejemplo n.º 7
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);
    }