示例#1
0
    private object CreateAndPopulateObject(JsonReader reader, Type objectType)
    {
      object newObject;

      if (ReflectionUtils.HasDefaultConstructor(objectType))
      {
        newObject = Activator.CreateInstance(objectType);

        PopulateObject(newObject, reader, objectType);
        return newObject;
      }
      else
      {
        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
        IDictionary<ParameterInfo, object> constructorParameters = c.GetParameters().ToDictionary(p => p, p => (object)null);
        MemberMappingCollection mappings = GetMemberMappings(objectType);

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

              ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, memberName).Key;
              MemberMapping mapping;

              if (matchingConstructorParameter != null && mappings.TryGetMapping(memberName, out mapping) && !mapping.Ignored)
              {
                constructorParameters[matchingConstructorParameter] = CreateObject(reader, matchingConstructorParameter.ParameterType, null, mapping.MemberConverter);
              }
              else
              {
                // skip token and all child tokens
                reader.Skip();
              }
              break;
            case JsonToken.EndObject:
              exit = true;
              break;
            default:
              throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
          }
        }

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

        return newObject;
      }
    }
示例#2
0
    private void SetObjectMember(JsonReader reader, object target, Type targetType, string memberName)
    {
      if (!reader.Read())
        throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

      MemberMappingCollection memberMappings = GetMemberMappings(targetType);
      Type memberType;
      object value;

      // test if a member with memberName exists on the type
      // otherwise test if target is a dictionary and assign value with the key if it is
      if (memberMappings.Contains(memberName))
      {
        MemberMapping memberMapping = memberMappings[memberName];

        if (memberMapping.Ignored)
        {
          reader.Skip();
          return;
        }

        // get the member's underlying 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;
        }

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

        if (_nullValueHandling == NullValueHandling.Ignore && value == null)
          return;

        if (_defaultValueHandling == DefaultValueHandling.Ignore && object.Equals(value, memberMapping.DefaultValue))
          return;

        if (!useExistingValue)
          ReflectionUtils.SetMemberValue(memberMapping.Member, target, value);
      }
      else
      {
        if (_missingMemberHandling == MissingMemberHandling.Error)
          throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, targetType.GetType().Name));
      }
    }