コード例 #1
0
        private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContract collectionValueContract)
        {
            contract.InvokeOnSerializing(value, Serializer.Context);

              SerializeStack.Add(value);
              writer.WriteStartObject();

              bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
              if (isReference)
              {
            writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
            writer.WriteValue(Serializer.ReferenceResolver.GetReference(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))
              {
            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);
        }
コード例 #2
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 ||
                          property.DefaultValueHandling == DefaultValueHandling.Ignore ||
                          property.ShouldSerialize != 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;
        }
コード例 #3
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;
        }
コード例 #4
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 (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.");
        }
コード例 #5
0
        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);
        }