Contract details for a System.Type used by the JsonSerializer.
상속: Newtonsoft.Json.Serialization.JsonContainerContract
        protected override System.Collections.Generic.IList<JsonProperty> CreateProperties(JsonObjectContract contract)
        {
            IList<JsonProperty> properties = base.CreateProperties(contract);

            properties = properties.Where(p => !notSerilizingProperties.Contains(p.PropertyName) ).ToList();
            return properties;
        }
 // Token: 0x06000BDB RID: 3035
 // RVA: 0x00046004 File Offset: 0x00044204
 public object CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, string id, out bool createdFromNonDefaultCreator)
 {
     object obj = null;
     if (objectContract.OverrideCreator != null)
     {
         if (objectContract.CreatorParameters.Count > 0)
         {
             createdFromNonDefaultCreator = true;
             return this.CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.OverrideCreator, id);
         }
         obj = objectContract.OverrideCreator(new object[0]);
     }
     else if (objectContract.DefaultCreator != null && (!objectContract.DefaultCreatorNonPublic || this.Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParametrizedCreator == null))
     {
         obj = objectContract.DefaultCreator();
     }
     else if (objectContract.ParametrizedCreator != null)
     {
         createdFromNonDefaultCreator = true;
         return this.CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.ParametrizedCreator, id);
     }
     if (obj != null)
     {
         createdFromNonDefaultCreator = false;
         return obj;
     }
     if (!objectContract.IsInstantiable)
     {
         throw JsonSerializationException.Create(reader, StringUtils.FormatWith("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.", CultureInfo.InvariantCulture, objectContract.UnderlyingType));
     }
     throw JsonSerializationException.Create(reader, StringUtils.FormatWith("Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.", CultureInfo.InvariantCulture, objectContract.UnderlyingType));
 }
        protected override System.Collections.Generic.IList<JsonProperty> CreateProperties(JsonObjectContract contract)
        {
            IList<JsonProperty> properties = base.CreateProperties(contract);

               	if(contract.UnderlyingType != typeof(MonoReports.Model.Thickness))
                properties = properties.Where(p =>!notSerilizingProperties.Contains(p.PropertyName) ).ToList();
            return properties;
        }
예제 #4
0
 public ModelFilterContext(
     Type systemType,
     JsonObjectContract jsonObjectContract,
     ISchemaRegistry schemaRegistry)
 {
     SystemType = systemType;
     JsonObjectContract = jsonObjectContract;
     SchemaRegistry = schemaRegistry;
 }
    protected override IList<JsonProperty> CreateProperties(JsonObjectContract contract)
    {
      IList<JsonProperty> properties = base.CreateProperties(contract);

      // only serializer properties that start with the specified character
      properties = 
        properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList();

      return properties;
    }
        protected override IList<JsonProperty> CreateProperties(JsonObjectContract contract)
        {
            var properties = base.CreateProperties(contract);

            foreach (var property in properties)
            {
                property.PropertyName = PascalCaseToElement(property.PropertyName);
            }

            var result = properties;
            return result;
        }
 private void SortUnsortedProperties(JsonObjectContract objContract)
 {
     if (objContract != null)
     {
         var order = 1;
         foreach (var property in objContract.Properties.Where(each => (each.Order == null) || (each.Order > 0)))
         {
             if (property.PropertyName == "name" || property.PropertyName == "#name")
             {
                 property.Order = -50;
             }
             else
             {
                 property.Order = order++;
             }
         }
     }
 }
        public JsonObjectContract ModifyContract(JsonObjectContract contract)
        {
            foreach (var property in contract.Properties)
            {
                foreach (var type in property.PropertyType.GetInterfaces().Union(new Type[] { property.PropertyType }))
                {
                    if (type.IsGenericType)
                    {
                        if (type.GetGenericTypeDefinition() == typeof(NestedList<>))
                        {
                            property.PropertyName = property.PropertyName + "$$nested";
                        }
                    }
                }
            }

            return contract;
        }
        public object CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, string id, out bool createdFromNonDefaultCreator)
        {
            object newObject = null;

            if (objectContract.OverrideCreator != null)
            {
                if (objectContract.CreatorParameters.Count > 0)
                {
                    createdFromNonDefaultCreator = true;
                    return CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.OverrideCreator, id);
                }

                newObject = objectContract.OverrideCreator(new object[0]);
            }
            else if (objectContract.DefaultCreator != null &&
                     (!objectContract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParametrizedCreator == null))
            {
                // use the default constructor if it is...
                // public
                // non-public and the user has change constructor handling settings
                // non-public and there is no other creator
                newObject = objectContract.DefaultCreator();
            }
            else if (objectContract.ParametrizedCreator != null)
            {
                createdFromNonDefaultCreator = true;
                return CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.ParametrizedCreator, id);
            }

            if (newObject == null)
            {
                if (!objectContract.IsInstantiable)
                    throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType));

                throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType));
            }

            createdFromNonDefaultCreator = false;
            return newObject;
        }
예제 #10
0
        private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
        {
            IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>();
              bool exit = false;
              do
              {
            switch (reader.TokenType)
            {
              case JsonToken.PropertyName:
            string memberName = reader.Value.ToString();

            // attempt exact case match first
            // then try match ignoring case
            JsonProperty property = contract.ConstructorParameters.GetClosestMatchProperty(memberName) ??
              contract.Properties.GetClosestMatchProperty(memberName);

            if (property != null)
            {
              if (property.PropertyContract == null)
                property.PropertyContract = GetContractSafe(property.PropertyType);

              JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, containerProperty);

              if (!ReadForType(reader, property.PropertyContract, propertyConverter != null))
                throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

              if (!property.Ignored)
              {
                if (property.PropertyContract == null)
                  property.PropertyContract = GetContractSafe(property.PropertyType);

                object propertyValue;
                if (propertyConverter != null && propertyConverter.CanRead)
                  propertyValue = DeserializeConvertable(propertyConverter, reader, property.PropertyType, null);
                else
                  propertyValue = CreateValueInternal(reader, property.PropertyType, property.PropertyContract, property, contract, containerProperty, null);

                propertyValues[property] = propertyValue;
              }
              else
              {
                reader.Skip();
              }
            }
            else
            {
              if (!reader.Read())
                throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

              if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
                TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}.".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType)), null);

              if (Serializer._missingMemberHandling == MissingMemberHandling.Error)
                throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));

              reader.Skip();
            }
            break;
              case JsonToken.Comment:
            break;
              case JsonToken.EndObject:
            exit = true;
            break;
              default:
            throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
            }
              } while (!exit && reader.Read());

              return propertyValues;
        }
예제 #11
0
    private void GenerateObjectSchema(Type type, JsonObjectContract contract)
    {
      CurrentSchema.Properties = new Dictionary<string, JsonSchema>();
      foreach (JsonProperty property in contract.Properties)
      {
        if (!property.Ignored)
        {
          bool optional = property.NullValueHandling == NullValueHandling.Ignore ||
                          HasFlag(property.DefaultValueHandling.GetValueOrDefault(), DefaultValueHandling.Ignore) ||
                          property.ShouldSerialize != null ||
                          property.GetIsSpecified != null;

          JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required, !optional);

          if (property.DefaultValue != null)
            propertySchema.Default = JToken.FromObject(property.DefaultValue);

          CurrentSchema.Properties.Add(property.PropertyName, propertySchema);
        }
      }

      if (type.IsSealed)
        CurrentSchema.AllowAdditionalProperties = false;
    }
예제 #12
0
        private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id)
        {
            contract.InvokeOnDeserializing(newObject, base.Serializer.Context);
            Dictionary <JsonProperty, PropertyPresence> dictionary = contract.Properties.ToDictionary((JsonProperty m) => m, (JsonProperty m) => PropertyPresence.None);

            if (id != null)
            {
                base.Serializer.ReferenceResolver.AddReference(this, id, newObject);
            }
            int depth = reader.Depth;

            do
            {
                switch (reader.TokenType)
                {
                case JsonToken.PropertyName:
                    {
                        string text = reader.Value.ToString();
                        try
                        {
                            JsonProperty key = contract.Properties.GetClosestMatchProperty(text);
                            if (key == null)
                            {
                                if (base.Serializer.MissingMemberHandling == MissingMemberHandling.Error)
                                {
                                    throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, text, contract.UnderlyingType.Name));
                                }
                                reader.Skip();
                            }
                            else
                            {
                                if (!ReadForType(reader, key.PropertyType, key.Converter))
                                {
                                    throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text));
                                }
                                SetPropertyPresence(reader, key, dictionary);
                                SetPropertyValue(key, reader, newObject);
                            }
                        }
                        catch (Exception ex)
                        {
                            if (IsErrorHandled(newObject, contract, text, ex))
                            {
                                HandleError(reader, depth);
                                break;
                            }
                            throw;
                        }
                        break;
                    }

                case JsonToken.EndObject:
                    foreach (KeyValuePair <JsonProperty, PropertyPresence> item in dictionary)
                    {
                        JsonProperty key = item.Key;
                        switch (item.Value)
                        {
                        case PropertyPresence.None:
                            if (key.Required == Required.AllowNull || key.Required == Required.Always)
                            {
                                throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, key.PropertyName));
                            }
                            if (HasFlag(key.DefaultValueHandling.GetValueOrDefault(base.Serializer.DefaultValueHandling), DefaultValueHandling.Populate) && key.Writable)
                            {
                                key.ValueProvider.SetValue(newObject, EnsureType(key.DefaultValue, CultureInfo.InvariantCulture, key.PropertyType));
                            }
                            break;

                        case PropertyPresence.Null:
                            if (key.Required == Required.Always)
                            {
                                throw new JsonSerializationException("Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, key.PropertyName));
                            }
                            break;
                        }
                    }
                    contract.InvokeOnDeserialized(newObject, base.Serializer.Context);
                    return(newObject);

                default:
                    throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);

                case JsonToken.Comment:
                    break;
                }
            }while (reader.Read());
            throw new JsonSerializationException("Unexpected end when deserializing object.");
        }
    private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, string id)
    {
      Type objectType = contract.UnderlyingType;

      if (contract.ParametrizedConstructor == null)
        throw new JsonSerializationException("Unable to find a constructor to use for type {0}. A class should either have a default constructor or only one constructor with arguments.".FormatWith(CultureInfo.InvariantCulture, objectType));

      // create a dictionary to put retrieved values into
      IDictionary<JsonProperty, object> propertyValues = contract.Properties.Where(p => !p.Ignored).ToDictionary(kv => kv, kv => (object)null);

      bool exit = false;
      do
      {
        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));

            // attempt exact case match first
            // then try match ignoring case
            JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);

            if (property != null)
            {
              if (!property.Ignored)
                propertyValues[property] = CreateValueProperty(reader, property, null, true, null);
              else
                reader.Skip();
            }
            else
            {
              if (Serializer.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);
        }
      } while (!exit && reader.Read());

      IDictionary<ParameterInfo, object> constructorParameters = contract.ParametrizedConstructor.GetParameters().ToDictionary(p => p, p => (object)null);
      IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();

      foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
      {
        ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key;
        if (matchingConstructorParameter != null)
          constructorParameters[matchingConstructorParameter] = propertyValue.Value;
        else
          remainingPropertyValues.Add(propertyValue);
      }

      object createdObject = contract.ParametrizedConstructor.Invoke(constructorParameters.Values.ToArray());

      if (id != null)
        Serializer.ReferenceResolver.AddReference(id, createdObject);

      contract.InvokeOnDeserializing(createdObject, Serializer.Context);

      // go through unused values and set the newly created object's properties
      foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
      {
        JsonProperty property = remainingPropertyValue.Key;
        object value = remainingPropertyValue.Value;

        if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
          property.ValueProvider.SetValue(createdObject, value);
      }

      contract.InvokeOnDeserialized(createdObject, Serializer.Context);
      return createdObject;
    }
		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))
					{
						object memberValue = property.ValueProvider.GetValue(value);
						JsonContract memberContract = 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 object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id)
    {
      ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo");

      Type objectType = contract.UnderlyingType;

      IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, reader, objectType);

      IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object) null);
      IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();

      foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
      {
        ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key;
        if (matchingConstructorParameter != null)
          constructorParameters[matchingConstructorParameter] = propertyValue.Value;
        else
          remainingPropertyValues.Add(propertyValue);
      }

      object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray());

      if (id != null)
        Serializer.ReferenceResolver.AddReference(this, id, createdObject);

      contract.InvokeOnDeserializing(createdObject, Serializer.Context);

      // go through unused values and set the newly created object's properties
      foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
      {
        JsonProperty property = remainingPropertyValue.Key;
        object value = remainingPropertyValue.Value;

        if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
        {
          property.ValueProvider.SetValue(createdObject, value);
        }
        else if (!property.Writable && value != null)
        {
          // handle readonly collection/dictionary properties
          JsonContract propertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType);

          if (propertyContract.ContractType == JsonContractType.Array)
          {
            JsonArrayContract propertyArrayContract = propertyContract as JsonArrayContract;

            object createdObjectCollection = property.ValueProvider.GetValue(createdObject);
            if (createdObjectCollection != null)
            {
              IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection);
              IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value);

              foreach (object newValue in newValues)
              {
                createdObjectCollectionWrapper.Add(newValue);
              }
            }
          }
          else if (propertyContract.ContractType == JsonContractType.Dictionary)
          {
            JsonDictionaryContract jsonDictionaryContract = propertyContract as JsonDictionaryContract;

            object createdObjectDictionary = property.ValueProvider.GetValue(createdObject);
            if (createdObjectDictionary != null)
            {
              IWrappedDictionary createdObjectDictionaryWrapper = jsonDictionaryContract.CreateWrapper(createdObjectDictionary);
              IWrappedDictionary newValues = jsonDictionaryContract.CreateWrapper(value);

              foreach (DictionaryEntry newValue in newValues)
              {
                createdObjectDictionaryWrapper.Add(newValue.Key, newValue.Value);
              }
            }
          }
        }
      }

      contract.InvokeOnDeserialized(createdObject, Serializer.Context);
      return createdObject;
    }
    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
        {
          object memberValue;
          JsonContract memberContract;

          if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue))
            continue;

          writer.WritePropertyName(property.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);
    }
예제 #17
0
        private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id)
        {
            ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo");
            Type underlyingType = contract.UnderlyingType;
            IDictionary <JsonProperty, object>  dictionary  = ResolvePropertyAndConstructorValues(contract, reader, underlyingType);
            IDictionary <ParameterInfo, object> dictionary2 = ((IEnumerable <ParameterInfo>)constructorInfo.GetParameters()).ToDictionary((Func <ParameterInfo, ParameterInfo>)((ParameterInfo p) => p), (Func <ParameterInfo, object>)((ParameterInfo p) => null));
            IDictionary <JsonProperty, object>  dictionary3 = new Dictionary <JsonProperty, object>();

            foreach (KeyValuePair <JsonProperty, object> item in dictionary)
            {
                ParameterInfo key = dictionary2.ForgivingCaseSensitiveFind((KeyValuePair <ParameterInfo, object> kv) => kv.Key.Name, item.Key.UnderlyingName).Key;
                if (key != null)
                {
                    dictionary2[key] = item.Value;
                }
                else
                {
                    dictionary3.Add(item);
                }
            }
            object obj = constructorInfo.Invoke(dictionary2.Values.ToArray());

            if (id != null)
            {
                base.Serializer.ReferenceResolver.AddReference(this, id, obj);
            }
            contract.InvokeOnDeserializing(obj, base.Serializer.Context);
            foreach (KeyValuePair <JsonProperty, object> item2 in dictionary3)
            {
                JsonProperty key2  = item2.Key;
                object       value = item2.Value;
                if (ShouldSetPropertyValue(item2.Key, item2.Value))
                {
                    key2.ValueProvider.SetValue(obj, value);
                }
                else
                {
                    if (key2.Writable || value == null)
                    {
                        continue;
                    }
                    JsonContract jsonContract = base.Serializer.ContractResolver.ResolveContract(key2.PropertyType);
                    if (jsonContract is JsonArrayContract)
                    {
                        JsonArrayContract jsonArrayContract = jsonContract as JsonArrayContract;
                        object            value2            = key2.ValueProvider.GetValue(obj);
                        if (value2 == null)
                        {
                            continue;
                        }
                        IWrappedCollection wrappedCollection  = jsonArrayContract.CreateWrapper(value2);
                        IWrappedCollection wrappedCollection2 = jsonArrayContract.CreateWrapper(value);
                        foreach (object item3 in wrappedCollection2)
                        {
                            wrappedCollection.Add(item3);
                        }
                    }
                    else
                    {
                        if (!(jsonContract is JsonDictionaryContract))
                        {
                            continue;
                        }
                        JsonDictionaryContract jsonDictionaryContract = jsonContract as JsonDictionaryContract;
                        object value3 = key2.ValueProvider.GetValue(obj);
                        if (value3 == null)
                        {
                            continue;
                        }
                        IWrappedDictionary wrappedDictionary  = jsonDictionaryContract.CreateWrapper(value3);
                        IWrappedDictionary wrappedDictionary2 = jsonDictionaryContract.CreateWrapper(value);
                        foreach (DictionaryEntry item4 in wrappedDictionary2)
                        {
                            wrappedDictionary.Add(item4.Key, item4.Value);
                        }
                    }
                }
            }
            contract.InvokeOnDeserialized(obj, base.Serializer.Context);
            return(obj);
        }
예제 #18
0
 /// <summary>
 /// Initializes a new instance of the <see cref="JsonPropertyCollection"/> class.
 /// </summary>
 /// <param name="contract">The contract.</param>
 public JsonPropertyCollection(JsonObjectContract contract)
 {
     ValidationUtils.ArgumentNotNull(contract, "contract");
     _contract = contract;
 }
        private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract)
        {
            contract.InvokeOnSerializing(value);

            string s;

            if (TryConvertToString(value, contract.UnderlyingType, out s))
            {
                writer.WriteValue(s);
                contract.InvokeOnSerialized(value);

                return;
            }

            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(value));
            }
            if (HasFlag(Serializer.TypeNameHandling, TypeNameHandling.Objects))
            {
                WriteTypeProperty(writer, contract.UnderlyingType);
            }

            int initialDepth = writer.Top;

            foreach (JsonProperty property in contract.Properties)
            {
                try
                {
                    if (!property.Ignored && property.Readable)
                    {
                        object       memberValue    = property.ValueProvider.GetValue(value);
                        JsonContract memberContract = GetContractSafe(memberValue);

                        WriteMemberInfoProperty(writer, value, 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);
        }
        private void SerializeObject(
            JsonWriter writer,
            object value,
            JsonObjectContract contract,
            JsonProperty member,
            JsonContainerContract collectionContract,
            JsonProperty containerProperty)
        {
            this.OnSerializing(writer, (JsonContract)contract, value);
            this._serializeStack.Add(value);
            this.WriteObjectStart(writer, value, (JsonContract)contract, member, collectionContract, containerProperty);
            int top = writer.Top;

            for (int index = 0; index < contract.Properties.Count; ++index)
            {
                JsonProperty property = contract.Properties[index];
                try
                {
                    JsonContract memberContract;
                    object       memberValue;
                    if (this.CalculatePropertyValues(writer, value, (JsonContainerContract)contract, member, property, out memberContract, out memberValue))
                    {
                        property.WritePropertyName(writer);
                        this.SerializeValue(writer, memberValue, memberContract, property, (JsonContainerContract)contract, member);
                    }
                }
                catch (Exception ex)
                {
                    if (this.IsErrorHandled(value, (JsonContract)contract, (object)property.PropertyName, (IJsonLineInfo)null, writer.ContainerPath, ex))
                    {
                        this.HandleError(writer, top);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            if (contract.ExtensionDataGetter != null)
            {
                IEnumerable <KeyValuePair <object, object> > keyValuePairs = contract.ExtensionDataGetter(value);
                if (keyValuePairs != null)
                {
                    foreach (KeyValuePair <object, object> keyValuePair in keyValuePairs)
                    {
                        JsonContract contractSafe1 = this.GetContractSafe(keyValuePair.Key);
                        JsonContract contractSafe2 = this.GetContractSafe(keyValuePair.Value);
                        string       propertyName  = this.GetPropertyName(writer, keyValuePair.Key, contractSafe1, out bool _);
                        if (this.ShouldWriteReference(keyValuePair.Value, (JsonProperty)null, contractSafe2, (JsonContainerContract)contract, member))
                        {
                            writer.WritePropertyName(propertyName);
                            this.WriteReference(writer, keyValuePair.Value);
                        }
                        else if (this.CheckForCircularReference(writer, keyValuePair.Value, (JsonProperty)null, contractSafe2, (JsonContainerContract)contract, member))
                        {
                            writer.WritePropertyName(propertyName);
                            this.SerializeValue(writer, keyValuePair.Value, contractSafe2, (JsonProperty)null, (JsonContainerContract)contract, member);
                        }
                    }
                }
            }
            writer.WriteEndObject();
            this._serializeStack.RemoveAt(this._serializeStack.Count - 1);
            this.OnSerialized(writer, (JsonContract)contract, value);
        }
예제 #21
0
        private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ConstructorInfo constructorInfo, string id)
        {
            ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo");

              // only need to keep a track of properies presence if they are required or a value should be defaulted if missing
              Dictionary<JsonProperty, PropertyPresence> propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate))
            ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None)
            : null;

              Type objectType = contract.UnderlyingType;

              if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
            TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using a non-default constructor '{1}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType, constructorInfo)), null);

              IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, containerProperty, reader, objectType);

              IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object) null);
              IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();

              foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
              {
            ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key;
            if (matchingConstructorParameter != null)
              constructorParameters[matchingConstructorParameter] = propertyValue.Value;
            else
              remainingPropertyValues.Add(propertyValue);

            if (propertiesPresence != null)
            {
              // map from constructor property to normal property
              var property = propertiesPresence.Keys.FirstOrDefault(p => p.PropertyName == propertyValue.Key.PropertyName);
              if (property != null)
            propertiesPresence[property] = (propertyValue.Value == null) ? PropertyPresence.Null : PropertyPresence.Value;
            }
              }

              object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray());

              if (id != null)
            AddReference(reader, id, createdObject);

              OnDeserializing(reader, contract, createdObject);

              // go through unused values and set the newly created object's properties
              foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
              {
            JsonProperty property = remainingPropertyValue.Key;
            object value = remainingPropertyValue.Value;

            if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
            {
              property.ValueProvider.SetValue(createdObject, value);
            }
            else if (!property.Writable && value != null)
            {
              // handle readonly collection/dictionary properties
              JsonContract propertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType);

              if (propertyContract.ContractType == JsonContractType.Array)
              {
            JsonArrayContract propertyArrayContract = (JsonArrayContract)propertyContract;

            object createdObjectCollection = property.ValueProvider.GetValue(createdObject);
            if (createdObjectCollection != null)
            {
              IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection);
              IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value);

              foreach (object newValue in newValues)
              {
                createdObjectCollectionWrapper.Add(newValue);
              }
            }
              }
              else if (propertyContract.ContractType == JsonContractType.Dictionary)
              {
            JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)propertyContract;

            object createdObjectDictionary = property.ValueProvider.GetValue(createdObject);
            if (createdObjectDictionary != null)
            {
              IDictionary targetDictionary = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(createdObjectDictionary) : (IDictionary) createdObjectDictionary;
              IDictionary newValues = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(value) : (IDictionary) value;

              foreach (DictionaryEntry newValue in newValues)
              {
                targetDictionary.Add(newValue.Key, newValue.Value);
              }
            }
              }
            }
              }

              EndObject(createdObject, reader, contract, reader.Depth, propertiesPresence);

              OnDeserialized(reader, contract, createdObject);
              return createdObject;
        }
예제 #22
0
        private static void SetExtensionDataDelegates(JsonObjectContract contract, MemberInfo member)
        {
            JsonExtensionDataAttribute attribute = ReflectionUtils.GetAttribute <JsonExtensionDataAttribute>(member);

            if (attribute == null)
            {
                return;
            }
            Type type = ReflectionUtils.GetMemberUnderlyingType(member);
            Type type2;

            ReflectionUtils.ImplementsGenericDefinition(type, typeof(IDictionary <, >), out type2);
            Type type3             = type2.GetGenericArguments()[0];
            Type type4             = type2.GetGenericArguments()[1];
            bool isJTokenValueType = typeof(JToken).IsAssignableFrom(type4);

            if (ReflectionUtils.IsGenericDefinition(type, typeof(IDictionary <, >)))
            {
                type = typeof(Dictionary <, >).MakeGenericType(new Type[]
                {
                    type3,
                    type4
                });
            }
            MethodInfo method = type.GetMethod("Add", new Type[]
            {
                type3,
                type4
            });
            Func <object, object>       getExtensionDataDictionary      = JsonTypeReflector.ReflectionDelegateFactory.CreateGet <object>(member);
            Action <object, object>     setExtensionDataDictionary      = JsonTypeReflector.ReflectionDelegateFactory.CreateSet <object>(member);
            Func <object>               createExtensionDataDictionary   = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor <object>(type);
            MethodCall <object, object> setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall <object>(method);
            ExtensionDataSetter         extensionDataSetter             = delegate(object o, string key, object value)
            {
                object obj = getExtensionDataDictionary(o);
                if (obj == null)
                {
                    obj = createExtensionDataDictionary();
                    setExtensionDataDictionary(o, obj);
                }
                if (isJTokenValueType && !(value is JToken))
                {
                    value = JToken.FromObject(value);
                }
                setExtensionDataDictionaryValue(obj, new object[]
                {
                    key,
                    value
                });
            };
            Type type5 = typeof(DefaultContractResolver.DictionaryEnumerator <, >).MakeGenericType(new Type[]
            {
                type3,
                type4
            });
            ConstructorInfo             method2 = type5.GetConstructors().First <ConstructorInfo>();
            MethodCall <object, object> createEnumerableWrapper = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall <object>(method2);
            ExtensionDataGetter         extensionDataGetter     = delegate(object o)
            {
                object obj = getExtensionDataDictionary(o);
                if (obj == null)
                {
                    return(null);
                }
                return((IEnumerable <KeyValuePair <object, object> >)createEnumerableWrapper(null, new object[]
                {
                    obj
                }));
            };

            if (attribute.ReadData)
            {
                contract.ExtensionDataSetter = extensionDataSetter;
            }
            if (attribute.WriteData)
            {
                contract.ExtensionDataGetter = extensionDataGetter;
            }
        }
        private void GenerateObjectSchema(JSchema schema, Type type, JsonObjectContract contract)
        {
            foreach (JsonProperty property in contract.Properties)
            {
                if (!property.Ignored)
                {
                    bool optional = property.NullValueHandling == NullValueHandling.Ignore ||
                                    HasFlag(property.DefaultValueHandling.GetValueOrDefault(), DefaultValueHandling.Ignore) ||
                                    property.ShouldSerialize != null ||
                                    property.GetIsSpecified != null;

                    Required required = property.Required;
                    if (DataAnnotationHelpers.GetRequired(property))
                        required = Required.Always;

                    JSchema propertySchema = GenerateInternal(property.PropertyType, required, property, contract);

                    if (property.DefaultValue != null)
                        propertySchema.Default = JToken.FromObject(property.DefaultValue);

                    schema.Properties.Add(property.PropertyName, propertySchema);

                    if (!optional)
                        schema.Required.Add(property.PropertyName);
                }
            }

            if (type.IsSealed())
                schema.AllowAdditionalProperties = false;
        }
예제 #24
0
        /// <summary>
        /// Creates a <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.
        /// </summary>
        /// <param name="contract">The member's declaring types <see cref="JsonObjectContract"/>.</param>
        /// <param name="member">The member to create a <see cref="JsonProperty"/> for.</param>
        /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.</returns>
        protected virtual JsonProperty CreateProperty(JsonObjectContract contract, MemberInfo member)
        {
            JsonProperty property = new JsonProperty();

            property.Member = member;

#if !PocketPC && !SILVERLIGHT && !MONO
            DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(member.DeclaringType);

            DataMemberAttribute dataMemberAttribute;
            if (dataContractAttribute != null)
            {
                dataMemberAttribute = JsonTypeReflector.GetAttribute <DataMemberAttribute>(member);
            }
            else
            {
                dataMemberAttribute = null;
            }
#endif

            JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute <JsonPropertyAttribute>(member);
            bool hasIgnoreAttribute = (JsonTypeReflector.GetAttribute <JsonIgnoreAttribute>(member) != null);

            string mappedName;
            if (propertyAttribute != null && propertyAttribute.PropertyName != null)
            {
                mappedName = propertyAttribute.PropertyName;
            }
#if !PocketPC && !SILVERLIGHT && !MONO
            else if (dataMemberAttribute != null && dataMemberAttribute.Name != null)
            {
                mappedName = dataMemberAttribute.Name;
            }
#endif
            else
            {
                mappedName = member.Name;
            }

            property.PropertyName = ResolvePropertyName(mappedName);

            if (propertyAttribute != null)
            {
                property.Required = propertyAttribute.IsRequired;
            }
#if !PocketPC && !SILVERLIGHT && !MONO
            else if (dataMemberAttribute != null)
            {
                property.Required = dataMemberAttribute.IsRequired;
            }
#endif
            else
            {
                property.Required = false;
            }

            property.Ignored = (hasIgnoreAttribute ||
                                (contract.MemberSerialization == MemberSerialization.OptIn &&
                                 propertyAttribute == null
#if !PocketPC && !SILVERLIGHT && !MONO
                                 && dataMemberAttribute == null
#endif
                                ));

            property.Readable = ReflectionUtils.CanReadMemberValue(member);
            property.Writable = ReflectionUtils.CanSetMemberValue(member);

            property.MemberConverter = JsonTypeReflector.GetConverter(member, ReflectionUtils.GetMemberUnderlyingType(member));

            DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute <DefaultValueAttribute>(member);
            property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;

            property.NullValueHandling     = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null;
            property.DefaultValueHandling  = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null;
            property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null;
            property.IsReference           = (propertyAttribute != null) ? propertyAttribute._isReference : null;

            return(property);
        }
    private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id)
    {
      contract.InvokeOnDeserializing(newObject, Serializer.Context);

      Dictionary<JsonProperty, PropertyPresence> propertiesPresence =
        contract.Properties.ToDictionary(m => m, m => PropertyPresence.None);

      if (id != null)
        Serializer.ReferenceResolver.AddReference(this, id, newObject);

      int initialDepth = reader.Depth;

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

              try
              {
                // attempt exact case match first
                // then try match ignoring case
                JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);

                if (property == null)
                {
                  if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
                    throw CreateSerializationException(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));

                  reader.Skip();
                  continue;
                }

                if (property.PropertyContract == null)
                  property.PropertyContract = GetContractSafe(property.PropertyType);

                JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter);

                if (!ReadForType(reader, property.PropertyContract, propertyConverter != null, false))
                  throw CreateSerializationException(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

                SetPropertyPresence(reader, property, propertiesPresence);

                SetPropertyValue(property, propertyConverter, reader, newObject);
              }
              catch (Exception ex)
              {
                if (IsErrorHandled(newObject, contract, memberName, reader.Path, ex))
                  HandleError(reader, initialDepth);
                else
                  throw;
              }
            }
            break;
          case JsonToken.EndObject:
            {
              foreach (KeyValuePair<JsonProperty, PropertyPresence> propertyPresence in propertiesPresence)
              {
                JsonProperty property = propertyPresence.Key;
                PropertyPresence presence = propertyPresence.Value;

                if (presence == PropertyPresence.None || presence == PropertyPresence.Null)
                {
                  try
                  {
                    switch (presence)
                    {
                      case PropertyPresence.None:
                        if (property.Required == Required.AllowNull || property.Required == Required.Always)
                          throw CreateSerializationException(reader, "Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));

                        if (property.PropertyContract == null)
                          property.PropertyContract = GetContractSafe(property.PropertyType);

                        if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Populate)
                            && property.Writable)
                          property.ValueProvider.SetValue(newObject, EnsureType(reader, property.DefaultValue, CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType));
                        break;
                      case PropertyPresence.Null:
                        if (property.Required == Required.Always)
                          throw CreateSerializationException(reader, "Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
                        break;
                    }
                  }
                  catch (Exception ex)
                  {
                    if (IsErrorHandled(newObject, contract, property.PropertyName, reader.Path, ex))
                      HandleError(reader, initialDepth);
                    else
                      throw;
                  }
                }
              }

              contract.InvokeOnDeserialized(newObject, Serializer.Context);
              return newObject;
            }
          case JsonToken.Comment:
            // ignore
            break;
          default:
            throw CreateSerializationException(reader, "Unexpected token when deserializing object: " + reader.TokenType);
        }
      } while (reader.Read());

      throw CreateSerializationException(reader, "Unexpected end when deserializing object.");
    }
예제 #26
0
        private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue)
        {
            CheckedRead(reader);
            string text = null;

            if (reader.TokenType == JsonToken.PropertyName)
            {
                bool flag;
                do
                {
                    string a = reader.Value.ToString();
                    if (string.Equals(a, "$ref", StringComparison.Ordinal))
                    {
                        CheckedRead(reader);
                        if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null)
                        {
                            throw new JsonSerializationException("JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, "$ref"));
                        }
                        string text2 = ((reader.Value != null) ? reader.Value.ToString() : null);
                        CheckedRead(reader);
                        if (text2 != null)
                        {
                            if (reader.TokenType == JsonToken.PropertyName)
                            {
                                throw new JsonSerializationException("Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, "$ref"));
                            }
                            return(base.Serializer.ReferenceResolver.ResolveReference(this, text2));
                        }
                        flag = true;
                    }
                    else if (string.Equals(a, "$type", StringComparison.Ordinal))
                    {
                        CheckedRead(reader);
                        string text3 = reader.Value.ToString();
                        CheckedRead(reader);
                        if ((member?.TypeNameHandling ?? base.Serializer.TypeNameHandling) != 0)
                        {
                            ReflectionUtils.SplitFullyQualifiedTypeName(text3, out var typeName, out var assemblyName);
                            Type type;
                            try
                            {
                                type = base.Serializer.Binder.BindToType(assemblyName, typeName);
                            }
                            catch (Exception innerException)
                            {
                                throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, text3), innerException);
                            }
                            if (type == null)
                            {
                                throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, text3));
                            }
                            if (!(objectType?.IsAssignableFrom(type) ?? true))
                            {
                                throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, type.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
                            }
                            objectType = type;
                            contract   = GetContractSafe(type);
                        }
                        flag = true;
                    }
                    else if (string.Equals(a, "$id", StringComparison.Ordinal))
                    {
                        CheckedRead(reader);
                        text = ((reader.Value != null) ? reader.Value.ToString() : null);
                        CheckedRead(reader);
                        flag = true;
                    }
                    else
                    {
                        if (string.Equals(a, "$values", StringComparison.Ordinal))
                        {
                            CheckedRead(reader);
                            object result = CreateList(reader, objectType, contract, member, existingValue, text);
                            CheckedRead(reader);
                            return(result);
                        }
                        flag = false;
                    }
                }while (flag && reader.TokenType == JsonToken.PropertyName);
            }
            if (!HasDefinedType(objectType))
            {
                return(CreateJObject(reader));
            }
            if (contract == null)
            {
                throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
            }
            JsonDictionaryContract jsonDictionaryContract = contract as JsonDictionaryContract;

            if (jsonDictionaryContract != null)
            {
                if (existingValue == null)
                {
                    return(CreateAndPopulateDictionary(reader, jsonDictionaryContract, text));
                }
                return(PopulateDictionary(jsonDictionaryContract.CreateWrapper(existingValue), reader, jsonDictionaryContract, text));
            }
            JsonObjectContract jsonObjectContract = contract as JsonObjectContract;

            if (jsonObjectContract != null)
            {
                if (existingValue == null)
                {
                    return(CreateAndPopulateObject(reader, jsonObjectContract, text));
                }
                return(PopulateObject(existingValue, reader, jsonObjectContract, text));
            }
            JsonPrimitiveContract jsonPrimitiveContract = contract as JsonPrimitiveContract;

            if (jsonPrimitiveContract != null && reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), "$value", StringComparison.Ordinal))
            {
                CheckedRead(reader);
                object result2 = CreateValueInternal(reader, objectType, jsonPrimitiveContract, member, existingValue);
                CheckedRead(reader);
                return(result2);
            }
            JsonISerializableContract jsonISerializableContract = contract as JsonISerializableContract;

            if (jsonISerializableContract != null)
            {
                return(CreateISerializable(reader, jsonISerializableContract, text));
            }
            throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
        }
예제 #27
0
        private IDictionary <JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonReader reader, Type objectType)
        {
            IDictionary <JsonProperty, object> dictionary = new Dictionary <JsonProperty, object>();
            bool flag = false;

            do
            {
                switch (reader.TokenType)
                {
                case JsonToken.PropertyName:
                {
                    string       text         = reader.Value.ToString();
                    JsonProperty jsonProperty = contract.ConstructorParameters.GetClosestMatchProperty(text) ?? contract.Properties.GetClosestMatchProperty(text);
                    if (jsonProperty != null)
                    {
                        if (!ReadForType(reader, jsonProperty.PropertyType, jsonProperty.Converter))
                        {
                            throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text));
                        }
                        if (!jsonProperty.Ignored)
                        {
                            dictionary[jsonProperty] = CreateValueProperty(reader, jsonProperty, null, gottenCurrentValue: true, null);
                        }
                        else
                        {
                            reader.Skip();
                        }
                        break;
                    }
                    if (!reader.Read())
                    {
                        throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text));
                    }
                    if (base.Serializer.MissingMemberHandling == MissingMemberHandling.Error)
                    {
                        throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, text, objectType.Name));
                    }
                    reader.Skip();
                    break;
                }

                case JsonToken.EndObject:
                    flag = true;
                    break;

                default:
                    throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);

                case JsonToken.Comment:
                    break;
                }
            }while (!flag && reader.Read());
            return(dictionary);
        }
예제 #28
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);
        }
    private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, string id)
    {
      object newObject = null;

      if (contract.UnderlyingType.IsInterface || contract.UnderlyingType.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, contract.UnderlyingType));

      if (contract.DefaultCreator != null &&
        (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
      {
        newObject = contract.DefaultCreator();
      }

      if (newObject != null)
      {
        PopulateObject(newObject, reader, contract, id);
        return newObject;
      }

      return CreateObjectFromNonDefaultConstructor(reader, contract, id);
    }
        /// <summary>
        /// Creates a <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.
        /// </summary>
        /// <param name="contract">The member's declaring types <see cref="JsonObjectContract"/>.</param>
        /// <param name="member">The member to create a <see cref="JsonProperty"/> for.</param>
        /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.</returns>
        protected virtual JsonProperty CreateProperty(JsonObjectContract contract, MemberInfo member)
        {
            JsonProperty property = new JsonProperty();

            property.PropertyType  = ReflectionUtils.GetMemberUnderlyingType(member);
            property.ValueProvider = CreateMemberValueProvider(member);

            // resolve converter for property
            // the class type might have a converter but the property converter takes presidence
            property.Converter = JsonTypeReflector.GetJsonConverter(member, property.PropertyType);

#if !PocketPC && !NET20
            DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(member.DeclaringType);

            DataMemberAttribute dataMemberAttribute;
            if (dataContractAttribute != null)
            {
                dataMemberAttribute = JsonTypeReflector.GetAttribute <DataMemberAttribute>(member);
            }
            else
            {
                dataMemberAttribute = null;
            }
#endif

            JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute <JsonPropertyAttribute>(member);
            bool hasIgnoreAttribute = (JsonTypeReflector.GetAttribute <JsonIgnoreAttribute>(member) != null);

            string mappedName;
            if (propertyAttribute != null && propertyAttribute.PropertyName != null)
            {
                mappedName = propertyAttribute.PropertyName;
            }
#if !PocketPC && !NET20
            else if (dataMemberAttribute != null && dataMemberAttribute.Name != null)
            {
                mappedName = dataMemberAttribute.Name;
            }
#endif
            else
            {
                mappedName = member.Name;
            }

            property.PropertyName = ResolvePropertyName(mappedName);

            if (propertyAttribute != null)
            {
                property.Required = propertyAttribute.Required;
            }
#if !PocketPC && !NET20
            else if (dataMemberAttribute != null)
            {
                property.Required = (dataMemberAttribute.IsRequired) ? Required.AllowNull : Required.Default;
            }
#endif
            else
            {
                property.Required = Required.Default;
            }

            property.Ignored = (hasIgnoreAttribute ||
                                (contract.MemberSerialization == MemberSerialization.OptIn &&
                                 propertyAttribute == null
#if !PocketPC && !NET20
                                 && dataMemberAttribute == null
#endif
                                ));

            bool allowNonPublicAccess = false;
            if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic)
            {
                allowNonPublicAccess = true;
            }
            if (propertyAttribute != null)
            {
                allowNonPublicAccess = true;
            }
#if !PocketPC && !NET20
            if (dataMemberAttribute != null)
            {
                allowNonPublicAccess = true;
            }
#endif

            property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess);
            property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess);

            property.MemberConverter = JsonTypeReflector.GetJsonConverter(member, ReflectionUtils.GetMemberUnderlyingType(member));

            DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute <DefaultValueAttribute>(member);
            property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;

            property.NullValueHandling      = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null;
            property.DefaultValueHandling   = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null;
            property.ReferenceLoopHandling  = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null;
            property.ObjectCreationHandling = (propertyAttribute != null) ? propertyAttribute._objectCreationHandling : null;
            property.TypeNameHandling       = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null;
            property.IsReference            = (propertyAttribute != null) ? propertyAttribute._isReference : null;

            property.ShouldSerialize = CreateShouldSerializeTest(member);

            return(property);
        }
    private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id)
    {
      contract.InvokeOnDeserializing(newObject, Serializer.Context);

      Dictionary<JsonProperty, RequiredValue> requiredProperties =
        contract.Properties.Where(m => m.Required != Required.Default).ToDictionary(m => m, m => RequiredValue.None);

      if (id != null)
        Serializer.ReferenceResolver.AddReference(id, newObject);

      int initialDepth = reader.Depth;

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

            // attempt exact case match first
            // then try match ignoring case
            JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);

            if (property == null)
            {
              if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
                throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));

              reader.Skip();
              continue;
            }

            if (property.PropertyType == typeof(byte[]))
            {
              reader.ReadAsBytes();
            }
            else
            {
              if (!reader.Read())
                throw new JsonSerializationException(
                  "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
            }

            SetRequiredProperty(reader, property, requiredProperties);

            try
            {
              SetPropertyValue(property, reader, newObject);
            }
            catch (Exception ex)
            {
              if (IsErrorHandled(newObject, contract, memberName, ex))
                HandleError(reader, initialDepth);
              else
                throw;
            }
            break;
          case JsonToken.EndObject:
            foreach (KeyValuePair<JsonProperty, RequiredValue> requiredProperty in requiredProperties)
            {
              if (requiredProperty.Value == RequiredValue.None)
                throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName));
              if (requiredProperty.Key.Required == Required.Always && requiredProperty.Value == RequiredValue.Null)
                throw new JsonSerializationException("Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName));
            }

            contract.InvokeOnDeserialized(newObject, Serializer.Context);
            return newObject;
          case JsonToken.Comment:
            // ignore
            break;
          default:
            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
        }
      } while (reader.Read());

      throw new JsonSerializationException("Unexpected end when deserializing object.");
    }
예제 #32
0
        private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id)
        {
            contract.InvokeOnDeserializing(newObject, Serializer.Context);

            Dictionary <JsonProperty, RequiredValue> requiredProperties =
                contract.Properties.Where(m => m.Required != Required.Default).ToDictionary(m => m, m => RequiredValue.None);

            if (id != null)
            {
                Serializer.ReferenceResolver.AddReference(id, newObject);
            }

            int initialDepth = reader.Depth;

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

                    // attempt exact case match first
                    // then try match ignoring case
                    JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);

                    if (property == null)
                    {
                        if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
                        {
                            throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));
                        }

                        reader.Skip();
                        continue;
                    }

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

                    SetRequiredProperty(reader, property, requiredProperties);

                    try
                    {
                        SetPropertyValue(property, reader, newObject);
                    }
                    catch (Exception ex)
                    {
                        if (IsErrorHandled(newObject, contract, memberName, ex))
                        {
                            HandleError(reader, initialDepth);
                        }
                        else
                        {
                            throw;
                        }
                    }
                    break;

                case JsonToken.EndObject:
                    foreach (KeyValuePair <JsonProperty, RequiredValue> requiredProperty in requiredProperties)
                    {
                        if (requiredProperty.Value == RequiredValue.None)
                        {
                            throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName));
                        }
                        if (requiredProperty.Key.Required == Required.Always && requiredProperty.Value == RequiredValue.Null)
                        {
                            throw new JsonSerializationException("Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName));
                        }
                    }

                    contract.InvokeOnDeserialized(newObject, Serializer.Context);
                    return(newObject);

                case JsonToken.Comment:
                    // ignore
                    break;

                default:
                    throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
                }
            } while (reader.Read());

            throw new JsonSerializationException("Unexpected end when deserializing object.");
        }
        private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor<object> creator, string id)
        {
            ValidationUtils.ArgumentNotNull(creator, "creator");

            // only need to keep a track of properies presence if they are required or a value should be defaulted if missing
            Dictionary<JsonProperty, PropertyPresence> propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate))
                ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None)
                : null;

            Type objectType = contract.UnderlyingType;

            if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
            {
                string parameters = string.Join(", ", contract.CreatorParameters.Select(p => p.PropertyName).ToArray());
                TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using creator with parameters: {1}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType, parameters)), null);
            }

            IDictionary<string, object> extensionData;
            IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndCreatorValues(contract, containerProperty, reader, objectType, out extensionData);

            object[] creatorParameterValues = new object[contract.CreatorParameters.Count];
            IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();

            foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
            {
                JsonProperty property = propertyValue.Key;

                JsonProperty matchingCreatorParameter;
                if (contract.CreatorParameters.Contains(property))
                {
                    matchingCreatorParameter = property;
                }
                else
                {
                    // check to see if a parameter with the same name as the underlying property name exists and match to that
                    matchingCreatorParameter = contract.CreatorParameters.ForgivingCaseSensitiveFind(p => p.PropertyName, property.UnderlyingName);
                }

                if (matchingCreatorParameter != null)
                {
                    int i = contract.CreatorParameters.IndexOf(matchingCreatorParameter);
                    creatorParameterValues[i] = propertyValue.Value;
                }
                else
                {
                    remainingPropertyValues.Add(propertyValue);
                }

                if (propertiesPresence != null)
                {
                    // map from creator property to normal property
                    JsonProperty presenceProperty = propertiesPresence.Keys.FirstOrDefault(p => p.PropertyName == property.PropertyName);
                    if (presenceProperty != null)
                        propertiesPresence[presenceProperty] = (propertyValue.Value == null) ? PropertyPresence.Null : PropertyPresence.Value;
                }
            }

            object createdObject = creator(creatorParameterValues);

            if (id != null)
                AddReference(reader, id, createdObject);

            OnDeserializing(reader, contract, createdObject);

            // go through unused values and set the newly created object's properties
            foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
            {
                JsonProperty property = remainingPropertyValue.Key;
                object value = remainingPropertyValue.Value;

                if (ShouldSetPropertyValue(property, value))
                {
                    property.ValueProvider.SetValue(createdObject, value);
                }
                else if (!property.Writable && value != null)
                {
                    // handle readonly collection/dictionary properties
                    JsonContract propertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType);

                    if (propertyContract.ContractType == JsonContractType.Array)
                    {
                        JsonArrayContract propertyArrayContract = (JsonArrayContract)propertyContract;

                        object createdObjectCollection = property.ValueProvider.GetValue(createdObject);
                        if (createdObjectCollection != null)
                        {
                            IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection);
                            IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value);

                            foreach (object newValue in newValues)
                            {
                                createdObjectCollectionWrapper.Add(newValue);
                            }
                        }
                    }
                    else if (propertyContract.ContractType == JsonContractType.Dictionary)
                    {
                        JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)propertyContract;

                        object createdObjectDictionary = property.ValueProvider.GetValue(createdObject);
                        if (createdObjectDictionary != null)
                        {
                            IDictionary targetDictionary = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(createdObjectDictionary) : (IDictionary)createdObjectDictionary;
                            IDictionary newValues = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(value) : (IDictionary)value;

                            foreach (DictionaryEntry newValue in newValues)
                            {
                                targetDictionary.Add(newValue.Key, newValue.Value);
                            }
                        }
                    }
                }
            }

            if (extensionData != null)
            {
                foreach (KeyValuePair<string, object> e in extensionData)
                {
                    contract.ExtensionDataSetter(createdObject, e.Key, e.Value);
                }
            }

            EndObject(createdObject, reader, contract, reader.Depth, propertiesPresence);

            OnDeserialized(reader, contract, createdObject);
            return createdObject;
        }
예제 #34
0
        private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            OnSerializing(writer, contract, value);

            _serializeStack.Add(value);

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

            int initialDepth = writer.Top;

            for (int index = 0; index < contract.Properties.Count; index++)
            {
                JsonProperty property = contract.Properties[index];
                try
                {
                    object       memberValue;
                    JsonContract memberContract;

                    if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue))
                    {
                        continue;
                    }

                    property.WritePropertyName(writer);
                    SerializeValue(writer, memberValue, memberContract, property, contract, member);
                }
                catch (Exception ex)
                {
                    if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex))
                    {
                        HandleError(writer, initialDepth);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            if (contract.ExtensionDataGetter != null)
            {
                IEnumerable <KeyValuePair <object, object> > extensionData = contract.ExtensionDataGetter(value);
                if (extensionData != null)
                {
                    foreach (KeyValuePair <object, object> e in extensionData)
                    {
                        JsonContract keyContract   = GetContractSafe(e.Key);
                        JsonContract valueContract = GetContractSafe(e.Value);

                        bool   escape;
                        string propertyName = GetPropertyName(writer, e.Key, keyContract, out escape);

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

                            writer.WritePropertyName(propertyName);

                            SerializeValue(writer, e.Value, valueContract, null, contract, member);
                        }
                    }
                }
            }

            writer.WriteEndObject();

            _serializeStack.RemoveAt(_serializeStack.Count - 1);

            OnSerialized(writer, contract, value);
        }
예제 #35
0
        private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id)
        {
            OnDeserializing(reader, contract, newObject);

              // only need to keep a track of properies presence if they are required or a value should be defaulted if missing
              Dictionary<JsonProperty, PropertyPresence> propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate))
            ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None)
            : null;

              if (id != null)
            AddReference(reader, id, newObject);

              int initialDepth = reader.Depth;

              bool finished = false;
              do
              {
            switch (reader.TokenType)
            {
              case JsonToken.PropertyName:
            {
              string memberName = reader.Value.ToString();

              try
              {
                // attempt exact case match first
                // then try match ignoring case
                JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);

                if (property == null)
                {
                  if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
                    TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType)), null);

                  if (Serializer._missingMemberHandling == MissingMemberHandling.Error)
                    throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));

                  if (!reader.Read())
                    break;

                  SetExtensionData(contract, member, reader, memberName, newObject);
                  continue;
                }

                if (property.PropertyContract == null)
                  property.PropertyContract = GetContractSafe(property.PropertyType);

                JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, member);

                if (!ReadForType(reader, property.PropertyContract, propertyConverter != null))
                  throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

                SetPropertyPresence(reader, property, propertiesPresence);

                // set extension data if property is ignored or readonly
                if (!SetPropertyValue(property, propertyConverter, contract, member, reader, newObject))
                  SetExtensionData(contract, member, reader, memberName, newObject);
              }
              catch (Exception ex)
              {
                if (IsErrorHandled(newObject, contract, memberName, reader as IJsonLineInfo, reader.Path, ex))
                  HandleError(reader, true, initialDepth);
                else
                  throw;
              }
            }
            break;
              case JsonToken.EndObject:
            finished = true;
            break;
              case JsonToken.Comment:
            // ignore
            break;
              default:
            throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
            }
              } while (!finished && reader.Read());

              if (!finished)
            ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object.");

              EndObject(newObject, reader, contract, initialDepth, propertiesPresence);

              OnDeserialized(reader, contract, newObject);
              return newObject;
        }
예제 #36
0
        private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue)
        {
            CheckedRead(reader);

            string id = null;

            if (reader.TokenType == JsonToken.PropertyName)
            {
                bool specialProperty;

                do
                {
                    string propertyName = reader.Value.ToString();

                    if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal))
                    {
                        CheckedRead(reader);
                        if (reader.TokenType != JsonToken.String)
                        {
                            throw new JsonSerializationException("JSON reference {0} property must have a string value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
                        }

                        string reference = reader.Value.ToString();

                        CheckedRead(reader);
                        if (reader.TokenType == JsonToken.PropertyName)
                        {
                            throw new JsonSerializationException("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(reference));
                    }
                    else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
                    {
                        CheckedRead(reader);
                        string qualifiedTypeName = reader.Value.ToString();

                        CheckedRead(reader);

                        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 new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex);
                            }

                            if (specifiedType == null)
                            {
                                throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName));
                            }

                            if (objectType != null && !objectType.IsAssignableFrom(specifiedType))
                            {
                                throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
                            }

                            objectType = specifiedType;
                            contract   = GetContractSafe(specifiedType);
                        }
                        specialProperty = true;
                    }
                    else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
                    {
                        CheckedRead(reader);

                        id = reader.Value.ToString();
                        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 new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
            }

            JsonDictionaryContract dictionaryContract = contract as JsonDictionaryContract;

            if (dictionaryContract != null)
            {
                if (existingValue == null)
                {
                    return(CreateAndPopulateDictionary(reader, dictionaryContract, id));
                }

                return(PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, id));
            }

            JsonObjectContract objectContract = contract as JsonObjectContract;

            if (objectContract != null)
            {
                if (existingValue == null)
                {
                    return(CreateAndPopulateObject(reader, objectContract, id));
                }

                return(PopulateObject(existingValue, reader, objectContract, id));
            }

#if !SILVERLIGHT && !PocketPC
            JsonISerializableContract serializableContract = contract as JsonISerializableContract;
            if (serializableContract != null)
            {
                return(CreateISerializable(reader, serializableContract, id));
            }
#endif

            throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
        }
예제 #37
0
        private void SetExtensionData(JsonObjectContract contract, JsonProperty member, JsonReader reader, string memberName, object o)
        {
            if (contract.ExtensionDataSetter != null)
              {
            try
            {
              object value = CreateValueInternal(reader, null, null, null, contract, member, null);

              contract.ExtensionDataSetter(o, memberName, value);
            }
            catch (Exception ex)
            {
              throw JsonSerializationException.Create(reader, "Error setting value in extension data for type '{0}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType), ex);
            }
              }
              else
              {
            reader.Skip();
              }
        }
예제 #38
0
        private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, string id)
        {
            Type objectType = contract.UnderlyingType;

            if (contract.ParametrizedConstructor == null)
            {
                throw new JsonSerializationException("Unable to find a constructor to use for type {0}. A class should either have a default constructor or only one constructor with arguments.".FormatWith(CultureInfo.InvariantCulture, objectType));
            }

            // create a dictionary to put retrieved values into
            IDictionary <JsonProperty, object> propertyValues = contract.Properties.Where(p => !p.Ignored).ToDictionary(kv => kv, kv => (object)null);

            bool exit = false;

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

                    // attempt exact case match first
                    // then try match ignoring case
                    JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);

                    if (property != null)
                    {
                        if (!property.Ignored)
                        {
                            propertyValues[property] = CreateValueProperty(reader, property, null, true, null);
                        }
                        else
                        {
                            reader.Skip();
                        }
                    }
                    else
                    {
                        if (Serializer.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);
                }
            } while (!exit && reader.Read());

            IDictionary <ParameterInfo, object> constructorParameters   = contract.ParametrizedConstructor.GetParameters().ToDictionary(p => p, p => (object)null);
            IDictionary <JsonProperty, object>  remainingPropertyValues = new Dictionary <JsonProperty, object>();

            foreach (KeyValuePair <JsonProperty, object> propertyValue in propertyValues)
            {
                ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key;
                if (matchingConstructorParameter != null)
                {
                    constructorParameters[matchingConstructorParameter] = propertyValue.Value;
                }
                else
                {
                    remainingPropertyValues.Add(propertyValue);
                }
            }

            object createdObject = contract.ParametrizedConstructor.Invoke(constructorParameters.Values.ToArray());

            if (id != null)
            {
                Serializer.ReferenceResolver.AddReference(id, createdObject);
            }

            contract.InvokeOnDeserializing(createdObject, Serializer.Context);

            // go through unused values and set the newly created object's properties
            foreach (KeyValuePair <JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
            {
                JsonProperty property = remainingPropertyValue.Key;
                object       value    = remainingPropertyValue.Value;

                if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
                {
                    property.ValueProvider.SetValue(createdObject, value);
                }
            }

            contract.InvokeOnDeserialized(createdObject, Serializer.Context);
            return(createdObject);
        }
예제 #39
0
        private void EndObject(object newObject, JsonReader reader, JsonObjectContract contract, int initialDepth, Dictionary<JsonProperty, PropertyPresence> propertiesPresence)
        {
            if (propertiesPresence != null)
              {
            foreach (KeyValuePair<JsonProperty, PropertyPresence> propertyPresence in propertiesPresence)
            {
              JsonProperty property = propertyPresence.Key;
              PropertyPresence presence = propertyPresence.Value;

              if (presence == PropertyPresence.None || presence == PropertyPresence.Null)
              {
            try
            {
              Required resolvedRequired = property._required ?? contract.ItemRequired ?? Required.Default;

              switch (presence)
              {
                case PropertyPresence.None:
                  if (resolvedRequired == Required.AllowNull || resolvedRequired == Required.Always)
                    throw JsonSerializationException.Create(reader, "Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));

                  if (property.PropertyContract == null)
                    property.PropertyContract = GetContractSafe(property.PropertyType);

                  if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) && property.Writable)
                    property.ValueProvider.SetValue(newObject, EnsureType(reader, property.GetResolvedDefaultValue(), CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType));
                  break;
                case PropertyPresence.Null:
                  if (resolvedRequired == Required.Always)
                    throw JsonSerializationException.Create(reader, "Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
                  break;
              }
            }
            catch (Exception ex)
            {
              if (IsErrorHandled(newObject, contract, property.PropertyName, reader as IJsonLineInfo, reader.Path, ex))
                HandleError(reader, true, initialDepth);
              else
                throw;
            }
              }
            }
              }
        }
        private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id)
        {
            ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo");
            Type underlyingType = contract.UnderlyingType;
            IDictionary <JsonProperty, object>  dictionary  = ResolvePropertyAndConstructorValues(contract, reader, underlyingType);
            IDictionary <ParameterInfo, object> dictionary2 = ((IEnumerable <ParameterInfo>)constructorInfo.GetParameters()).ToDictionary((Func <ParameterInfo, ParameterInfo>)((ParameterInfo p) => p), (Func <ParameterInfo, object>)((ParameterInfo p) => null));
            IDictionary <JsonProperty, object>  dictionary3 = new Dictionary <JsonProperty, object>();

            foreach (KeyValuePair <JsonProperty, object> item in dictionary)
            {
                ParameterInfo key = dictionary2.ForgivingCaseSensitiveFind((KeyValuePair <ParameterInfo, object> kv) => kv.Key.Name, item.Key.UnderlyingName).Key;
                if (key != null)
                {
                    dictionary2[key] = item.Value;
                }
                else
                {
                    dictionary3.Add(item);
                }
            }
            object obj = constructorInfo.Invoke(dictionary2.Values.ToArray());

            if (id != null)
            {
                base.Serializer.ReferenceResolver.AddReference(this, id, obj);
            }
            contract.InvokeOnDeserializing(obj, base.Serializer.Context);
            foreach (KeyValuePair <JsonProperty, object> item2 in dictionary3)
            {
                JsonProperty key2  = item2.Key;
                object       value = item2.Value;
                if (ShouldSetPropertyValue(item2.Key, item2.Value))
                {
                    key2.ValueProvider.SetValue(obj, value);
                }
                else if (!key2.Writable && value != null)
                {
                    JsonContract jsonContract = base.Serializer.ContractResolver.ResolveContract(key2.PropertyType);
                    if (jsonContract is JsonArrayContract)
                    {
                        JsonArrayContract jsonArrayContract = jsonContract as JsonArrayContract;
                        object            value2            = key2.ValueProvider.GetValue(obj);
                        if (value2 != null)
                        {
                            IWrappedCollection wrappedCollection  = jsonArrayContract.CreateWrapper(value2);
                            IWrappedCollection wrappedCollection2 = jsonArrayContract.CreateWrapper(value);
                            IEnumerator        enumerator3        = wrappedCollection2.GetEnumerator();
                            try
                            {
                                while (enumerator3.MoveNext())
                                {
                                    object current3 = enumerator3.Current;
                                    wrappedCollection.Add(current3);
                                }
                            }
                            finally
                            {
                                IDisposable disposable;
                                if ((disposable = (enumerator3 as IDisposable)) != null)
                                {
                                    disposable.Dispose();
                                }
                            }
                        }
                    }
                    else if (jsonContract is JsonDictionaryContract)
                    {
                        JsonDictionaryContract jsonDictionaryContract = jsonContract as JsonDictionaryContract;
                        object value3 = key2.ValueProvider.GetValue(obj);
                        if (value3 != null)
                        {
                            IWrappedDictionary    wrappedDictionary  = jsonDictionaryContract.CreateWrapper(value3);
                            IWrappedDictionary    wrappedDictionary2 = jsonDictionaryContract.CreateWrapper(value);
                            IDictionaryEnumerator enumerator4        = wrappedDictionary2.GetEnumerator();
                            try
                            {
                                while (enumerator4.MoveNext())
                                {
                                    DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator4.Current;
                                    wrappedDictionary.Add(dictionaryEntry.Key, dictionaryEntry.Value);
                                }
                            }
                            finally
                            {
                                IDisposable disposable2;
                                if ((disposable2 = (enumerator4 as IDisposable)) != null)
                                {
                                    disposable2.Dispose();
                                }
                            }
                        }
                    }
                }
            }
            contract.InvokeOnDeserialized(obj, base.Serializer.Context);
            return(obj);
        }
예제 #41
0
        private Schema CreateObjectSchema(JsonObjectContract jsonContract)
        {
            var properties = jsonContract.Properties
                .Where(p => !p.Ignored)
                .Where(p => !(_ignoreObsoleteProperties && p.IsObsolete()))
                .ToDictionary(
                    prop => prop.PropertyName,
                    prop => CreateInlineSchema(prop.PropertyType).WithValidationProperties(prop)
                );

            var required = jsonContract.Properties.Where(prop => prop.IsRequired())
                .Select(propInfo => propInfo.PropertyName)
                .ToList();

            var schema = new Schema
            {
                required = required.Any() ? required : null, // required can be null but not empty
                properties = properties,
                type = "object"
            };

            foreach (var filter in _schemaFilters)
            {
                filter.Apply(schema, this, jsonContract.UnderlyingType);
            }

            // NOTE: In next major version, _modelFilters will completely replace _schemaFilters
            var modelFilterContext = new ModelFilterContext(jsonContract.UnderlyingType, jsonContract, this);
            foreach (var filter in _modelFilters)
            {
                filter.Apply(schema, modelFilterContext);
            }

            return schema;
        }
예제 #42
0
 /// <summary>
 ///     Make sure that JsonExtensionData doesn't serialize
 ///     $metadata fields or properties that are in the actual object.
 /// </summary>
 /// <param name="objContract">the Json object contract to tweak.</param>
 private static void FilterJsonExtensionData(JsonObjectContract objContract)
 {
     var orig = objContract?.ExtensionDataGetter;
     if (orig != null)
     {
         objContract.ExtensionDataGetter = o =>
         {
             return orig(o)?.Where(each =>
             {
                 var key = each.Key.ToString();
                 return !key.StartsWith("$") && objContract.Properties.All(p => p.PropertyName != key);
             });
         };
     }
 }
    private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonReader reader, Type objectType)
    {
      IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>();
      bool exit = false;
      do
      {
        switch (reader.TokenType)
        {
          case JsonToken.PropertyName:
            string memberName = reader.Value.ToString();

            // attempt exact case match first
            // then try match ignoring case
            JsonProperty property = contract.ConstructorParameters.GetClosestMatchProperty(memberName) ??
              contract.Properties.GetClosestMatchProperty(memberName);

            if (property != null)
            {
              if (property.PropertyContract == null)
                property.PropertyContract = GetContractSafe(property.PropertyType);

              JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter);

              if (!ReadForType(reader, property.PropertyContract, propertyConverter != null, false))
                throw CreateSerializationException(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

              if (!property.Ignored)
                propertyValues[property] = CreateValueProperty(reader, property, propertyConverter, null, true, null);
              else
                reader.Skip();
            }
            else
            {
              if (!reader.Read())
                throw CreateSerializationException(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

              if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
                throw CreateSerializationException(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));

              reader.Skip();
            }
            break;
          case JsonToken.Comment:
            break;
          case JsonToken.EndObject:
            exit = true;
            break;
          default:
            throw CreateSerializationException(reader, "Unexpected token when deserializing object: " + reader.TokenType);
        }
      } while (!exit && reader.Read());

      return propertyValues;
    }
예제 #44
0
            static void EnableInvisibleMetadata(JsonObjectContract contract)
            {
                if (!typeof(DomainEvent).IsAssignableFrom(contract.UnderlyingType))
                    return;

                var property = contract.Properties["Meta"];

                property.Ignored = true;
                contract.OnDeserializedCallbacks.Add((target, context) =>
                                                         property.ValueProvider.SetValue(target, new Metadata()));
            }
    private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, string id)
    {
      object newObject = null;

      if (contract.UnderlyingType.IsInterface() || contract.UnderlyingType.IsAbstract())
        throw CreateSerializationException(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));

      if (contract.OverrideConstructor != null)
      {
        if (contract.OverrideConstructor.GetParameters().Length > 0)
          return CreateObjectFromNonDefaultConstructor(reader, contract, contract.OverrideConstructor, id);

        newObject = contract.OverrideConstructor.Invoke(null);
      }
      else if (contract.DefaultCreator != null &&
        (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || contract.ParametrizedConstructor == null))
      {
        // use the default constructor if it is...
        // public
        // non-public and the user has change constructor handling settings
        // non-public and there is no other constructor
        newObject = contract.DefaultCreator();
      }
      else if (contract.ParametrizedConstructor != null)
      {
        return CreateObjectFromNonDefaultConstructor(reader, contract, contract.ParametrizedConstructor, id);
      }

      if (newObject == null)
        throw CreateSerializationException(reader, "Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));

      PopulateObject(newObject, reader, contract, id);
      return newObject;
    }
예제 #46
0
 protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
 {
     var contract = new JsonObjectContract(type);
     return base.CreateProperties(contract.CreatedType, contract.MemberSerialization);
 }
        private object CreateObjectFromNonDefaultConstructor(JsonObjectContract contract, JsonReader reader)
        {
            Type objectType = contract.UnderlyingType;

            // 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
            IDictionary <JsonProperty, object> propertyValues = contract.Properties.Where(p => !p.Ignored).ToDictionary(kv => kv, kv => (object)null);

            bool exit = false;

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

                    JsonProperty property;
                    // attempt exact case match first
                    // then try match ignoring case
                    if (contract.Properties.TryGetClosestMatchProperty(memberName, out property))
                    {
                        if (!property.Ignored)
                        {
                            Type memberType = ReflectionUtils.GetMemberUnderlyingType(property.Member);
                            propertyValues[property] = CreateValue(reader, memberType, null, property.MemberConverter);
                        }
                    }
                    else
                    {
                        if (_serializer.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);
                }
            } while (!exit && reader.Read());

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

            foreach (KeyValuePair <JsonProperty, object> propertyValue in propertyValues)
            {
                ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key;
                if (matchingConstructorParameter != null)
                {
                    constructorParameters[matchingConstructorParameter] = propertyValue.Value;
                }
                else
                {
                    remainingPropertyValues.Add(propertyValue);
                }
            }

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

            contract.InvokeOnDeserializing(createdObject);

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

            contract.InvokeOnDeserialized(createdObject);
            return(createdObject);
        }
예제 #48
0
        private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id)
        {
            contract.InvokeOnDeserializing(newObject);

            Dictionary <string, bool> requiredProperties =
                contract.Properties.Where(m => m.Required).ToDictionary(m => m.PropertyName, m => false);

            if (id != null)
            {
                Serializer.ReferenceResolver.AddReference(id, newObject);
            }

            int initialDepth = reader.Depth;

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

                    // set required property even if null (matches WCF IsRequired behavour)
                    SetRequiredProperty(memberName, requiredProperties);

                    try
                    {
                        SetObjectMember(reader, newObject, contract, memberName);
                    }
                    catch (Exception ex)
                    {
                        if (IsErrorHandled(newObject, contract, memberName, ex))
                        {
                            HandleError(reader, initialDepth);
                        }
                        else
                        {
                            throw;
                        }
                    }
                    break;

                case JsonToken.EndObject:
                    foreach (KeyValuePair <string, bool> requiredProperty in requiredProperties)
                    {
                        if (!requiredProperty.Value)
                        {
                            throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key));
                        }
                    }

                    contract.InvokeOnDeserialized(newObject);
                    return(newObject);

                case JsonToken.Comment:
                    // ignore
                    break;

                default:
                    throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
                }
            } while (reader.Read());

            throw new JsonSerializationException("Unexpected end when deserializing object.");
        }