private void GenerateObjectSchema(JSchema schema, Type type, JsonObjectContract contract)
        {
            IEnumerable <JsonProperty> properties;

            if (_generator.SchemaPropertyOrderHandling == SchemaPropertyOrderHandling.Alphabetical)
            {
                properties = contract.Properties
                             .OrderBy(p => p.Order ?? 0)
                             .ThenBy(p => p.PropertyName);
            }
            else
            {
                properties = contract.Properties;
            }

            foreach (JsonProperty property in properties)
            {
                if (!property.Ignored)
                {
                    Required?required = property._required;
                    if (DataAnnotationHelpers.GetRequired(property))
                    {
                        required = Required.Always;
                    }

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

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

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

                    Required resolvedRequired = required ?? _generator.DefaultRequired;
                    bool     optional;
                    switch (resolvedRequired)
                    {
                    case Required.Default:
                    case Required.DisallowNull:
                        optional = true;
                        break;

                    case Required.Always:
                    case Required.AllowNull:
                        optional = property.NullValueHandling == NullValueHandling.Ignore ||
                                   HasFlag(property.DefaultValueHandling.GetValueOrDefault(), DefaultValueHandling.Ignore) ||
                                   property.ShouldSerialize != null ||
                                   property.GetIsSpecified != null;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException("required");
                    }

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

            if (type.IsSealed())
            {
                schema.AllowAdditionalProperties = false;
            }
        }
 public ComplexDataTypeInfo(DataType dataType, Type underlyingClrType, JsonObjectContract jsonContract)
 {
     _dataType          = dataType;
     _underlyingClrType = underlyingClrType;
     _jsonContract      = jsonContract;
 }
Example #3
0
        protected void PopulateProperties(JsonSerializer serializer, object obj, JsonReader reader, JsonObjectContract contract)
        {
            foreach (var propName in ReaderUtil.IterateProperties(reader))
            {
                var successfullyPopulateProperty = ReaderUtil.TryPopulateProperty(
                    serializer,
                    obj,
                    contract.Properties.GetClosestMatchProperty(propName),
                    reader);

                //flatten out attributes onto the object
                if (!successfullyPopulateProperty && propName == "attributes")
                {
                    foreach (var innerPropName in ReaderUtil.IterateProperties(reader))
                    {
                        ReaderUtil.TryPopulateProperty(
                            serializer,
                            obj,
                            contract.Properties.GetClosestMatchProperty(innerPropName),
                            reader);
                    }
                }

                //flatten out relationships onto the object
                if (!successfullyPopulateProperty && propName == "relationships")
                {
                    foreach (var innerPropName in ReaderUtil.IterateProperties(reader))
                    {
                        ReaderUtil.TryPopulateProperty(
                            serializer,
                            obj,
                            contract.Properties.GetClosestMatchProperty(innerPropName),
                            reader);
                    }
                }
            }
        }
        protected object PopulateProperties(JsonSerializer serializer, object obj, JsonReader reader, JsonObjectContract contract)
        {
            foreach (var propName in ReaderUtil.IterateProperties(reader))
            {
                if (propName == PropertyNames.Type)
                {
                    var type = reader.Value;
                    if (obj.GetType().Name.ToLower() != type.ToString().ToLower())
                    {
                        Assembly[] assembly = Utility.GetAssemblies();
                        var        tp       = assembly.SelectMany(s => s.GetTypes()).ToList().Where(t => t.Name.ToLower() == type.ToString().ToLower()).SingleOrDefault();
                        if (tp != null)
                        {
                            obj      = Activator.CreateInstance(tp);
                            contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(obj.GetType());
                        }
                    }
                    //retObj.id = obj;
                }
                var successfullyPopulateProperty = ReaderUtil.TryPopulateProperty(
                    serializer,
                    obj,
                    contract.Properties.GetClosestMatchProperty(propName),
                    reader);

                if (!successfullyPopulateProperty)
                {
                    //flatten out attributes onto the object
                    if (propName == "attributes")
                    {
                        foreach (var innerPropName in ReaderUtil.IterateProperties(reader))
                        {
                            ReaderUtil.TryPopulateProperty(
                                serializer,
                                obj,
                                contract.Properties.GetClosestMatchProperty(innerPropName),
                                reader);
                        }
                    }

                    //flatten out relationships onto the object
                    if (propName == "relationships")
                    {
                        foreach (var innerPropName in ReaderUtil.IterateProperties(reader))
                        {
                            //read into the 'Data' path
                            var preDataPath = ReaderUtil.ReadUntilStart(reader, DataPathRegex);

                            ReaderUtil.TryPopulateProperty(
                                serializer,
                                obj,
                                contract.Properties.GetClosestMatchProperty(innerPropName),
                                reader);
                            //read out of the 'Data' path
                            ReaderUtil.ReadUntilEnd(reader, preDataPath);
                        }
                    }
                }
            }
            return(obj);
        }
        private static IList <Field> BuildForTypeRecursive(
            Type modelType,
            JsonObjectContract contract,
            IContractResolver contractResolver,
            Stack <Type> processedTypes)
        {
            Field BuildField(JsonProperty prop)
            {
                bool ShouldIgnore(Attribute attribute) =>
                attribute is JsonIgnoreAttribute || attribute is FieldBuilderIgnoreAttribute;

                IList <Attribute> attributes = prop.AttributeProvider.GetAttributes(true);

                if (attributes.Any(ShouldIgnore))
                {
                    return(null);
                }

                Field CreateComplexField(DataType dataType, Type underlyingClrType, JsonObjectContract jsonObjectContract)
                {
                    try
                    {
                        if (processedTypes.Contains(underlyingClrType))
                        {
                            // Skip recursive types.
                            return(null);
                        }

                        processedTypes.Push(underlyingClrType);
                        IList <Field> subFields =
                            BuildForTypeRecursive(underlyingClrType, jsonObjectContract, contractResolver, processedTypes);
                        return(new Field(prop.PropertyName, dataType, subFields));
                    }
                    finally
                    {
                        processedTypes.Pop();
                    }
                }

                Field CreateSimpleField(DataType dataType)
                {
                    var field = new Field(prop.PropertyName, dataType);

                    foreach (Attribute attribute in attributes)
                    {
                        switch (attribute)
                        {
                        case IsSearchableAttribute _:
                            field.IsSearchable = true;
                            break;

                        case IsFilterableAttribute _:
                            field.IsFilterable = true;
                            break;

                        case IsSortableAttribute _:
                            field.IsSortable = true;
                            break;

                        case IsFacetableAttribute _:
                            field.IsFacetable = true;
                            break;

                        case IsRetrievableAttribute isRetrievableAttribute:
                            field.IsRetrievable = isRetrievableAttribute.IsRetrievable;
                            break;

                        case AnalyzerAttribute analyzerAttribute:
                            field.Analyzer = analyzerAttribute.Name;
                            break;

                        case SearchAnalyzerAttribute searchAnalyzerAttribute:
                            field.SearchAnalyzer = searchAnalyzerAttribute.Name;
                            break;

                        case IndexAnalyzerAttribute indexAnalyzerAttribute:
                            field.IndexAnalyzer = indexAnalyzerAttribute.Name;
                            break;

                        case SynonymMapsAttribute synonymMapsAttribute:
                            field.SynonymMaps = synonymMapsAttribute.SynonymMaps;
                            break;

                        default:
                            Type attributeType = attribute.GetType();

                            // Match on name to avoid dependency - don't want to force people not using
                            // this feature to bring in the annotations component.
                            //
                            // Also, ignore key attributes on sub-fields.
                            if (attributeType.FullName == "System.ComponentModel.DataAnnotations.KeyAttribute" &&
                                processedTypes.Count <= 1)
                            {
                                field.IsKey = true;
                            }
                            break;
                        }
                    }

                    return(field);
                }

                ArgumentException FailOnUnknownDataType()
                {
                    string errorMessage =
                        $"Property '{prop.PropertyName}' is of type '{prop.PropertyType}', which does not map to an " +
                        "Azure Search data type. Please use a supported data type or mark the property with [JsonIgnore] or " +
                        "[FieldBuilderIgnore] and define the field by creating a Field object.";

                    return(new ArgumentException(errorMessage, nameof(modelType)));
                }

                IDataTypeInfo dataTypeInfo = GetDataTypeInfo(prop.PropertyType, contractResolver);

                return(dataTypeInfo.Match(
                           onUnknownDataType: () => throw FailOnUnknownDataType(),
                           onSimpleDataType: CreateSimpleField,
                           onComplexDataType: CreateComplexField));
            }

            return(contract.Properties.Select(BuildField).Where(field => field != null).ToArray());
        }
        private IDictionary<JsonProperty, object> ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType, out IDictionary<string, object> extensionData)
        {
            extensionData = (contract.ExtensionDataSetter != null) ? new Dictionary<string, object>() : null;

            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.CreatorParameters.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;
                                continue;
                            }
                        }
                        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));
                        }

                        if (extensionData != null)
                        {
                            object value = CreateValueInternal(reader, null, null, null, contract, containerProperty, null);
                            extensionData[memberName] = value;
                        }
                        else
                        {
                            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;
        }
        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.Ignored)
                                        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;
                        }
                    }
                }
            }
        }
 public static bool IsAmbiguous(this JsonObjectContract objectContract)
 {
     return(JsonContractExtensions.AmbiguousTypeNames.Contains <string>(((JsonContract)objectContract).get_UnderlyingType().FullName));
 }
Example #9
0
        protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            var contract = new JsonObjectContract(type);

            return(base.CreateProperties(contract.CreatedType, contract.MemberSerialization));
        }
Example #10
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }

            var obj = JObject.Load(reader);

            Stream stream;

            string type = obj.GetValue("@type", StringComparison.OrdinalIgnoreCase)?.ToString();

            if (type == null)
            {
                type = obj.GetValue("type", StringComparison.OrdinalIgnoreCase)?.ToString();
            }

            if (type == "General" || type == ((int)StreamType.General).ToString())
            {
                JsonObjectContract contract =
                    (JsonObjectContract)serializer.ContractResolver.ResolveContract(typeof(GeneralStream));
                stream = existingValue as GeneralStream ?? (GeneralStream)contract.DefaultCreator?.Invoke();
            }
            else if (type == "Video" || type == ((int)StreamType.Video).ToString())
            {
                JsonObjectContract contract =
                    (JsonObjectContract)serializer.ContractResolver.ResolveContract(typeof(VideoStream));
                stream = existingValue as VideoStream ?? (VideoStream)contract.DefaultCreator?.Invoke();
            }
            else if (type == "Audio" || type == ((int)StreamType.Audio).ToString())
            {
                JsonObjectContract contract =
                    (JsonObjectContract)serializer.ContractResolver.ResolveContract(typeof(AudioStream));
                stream = existingValue as AudioStream ?? (AudioStream)contract.DefaultCreator?.Invoke();
            }
            else if (type == "Text" || type == ((int)StreamType.Text).ToString())
            {
                JsonObjectContract contract =
                    (JsonObjectContract)serializer.ContractResolver.ResolveContract(typeof(TextStream));
                stream = existingValue as TextStream ?? (TextStream)contract.DefaultCreator?.Invoke();
            }
            else if (type == "Menu" || type == ((int)StreamType.Menu).ToString())
            {
                JsonObjectContract contract =
                    (JsonObjectContract)serializer.ContractResolver.ResolveContract(typeof(MenuStream));
                stream = existingValue as MenuStream ?? (MenuStream)contract.DefaultCreator?.Invoke();
            }
            else
            {
                return(null);
            }

            if (stream == null)
            {
                return(null);
            }

            using (var subReader = obj.CreateReader())
            {
                serializer.Populate(subReader, stream);
            }
            return(stream);
        }
 public override object Create(JsonReader reader, JsonSerializerReader internalReader, JsonObjectContract objectContract, string id, string unityGuid, Type objectType, out bool exit)
 {
     exit = false;
     return(null);
 }
Example #12
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;
        }
        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.");
        }
        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;
        }
        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);
        }
Example #16
0
 public abstract void ModifyContract(Type objectType, JsonObjectContract contract);
Example #17
0
        GetProperties(this Exception exception, DefaultContractResolver defaultContractResolver, JsonObjectContract serializer)
        {
            // Validate parameters.
            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }

            // If null, return null.
            return(serializer?.Properties.Select(p => (defaultContractResolver.GetResolvedPropertyName(p.PropertyName), p.PropertyType.GetTypeInfo(), p.ValueProvider.GetValue(exception))));
        }
Example #18
0
 internal static IEnumerable <IValueProvider> GetConstructorParameterValueProviders(this JsonObjectContract contract)
 {
     return(contract.CreatorParameters.Select(p => contract.GetConstructorParameterValueProvider(p)).ToArray());
 }
        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();

                        if (CheckPropertyName(reader, memberName))
                            continue;

                        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;
        }
Example #20
0
 // Token: 0x0600098F RID: 2447 RVA: 0x00036EA0 File Offset: 0x000350A0
 private bool method_12(object object_0, JsonObjectContract jsonObjectContract_0, JsonProperty jsonProperty_0)
 {
     return((object_0 != null || base.method_1(jsonObjectContract_0, jsonProperty_0) != NullValueHandling.Ignore) && (!this.method_25(jsonProperty_0.DefaultValueHandling.GetValueOrDefault(this.jsonSerializer_0.defaultValueHandling_0), DefaultValueHandling.Ignore) || !Class80.smethod_0(object_0, jsonProperty_0.method_2())));
 }
        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>
        /// Serializes an object into a JSON string adding Properties.
        /// </summary>
        /// <param name="writer">The JSON writer.</param>
        /// <param name="value">The value to serialize.</param>
        /// <param name="serializer">The JSON serializer.</param>
        public override void WriteJson(JsonWriter writer,
                                       object value, JsonSerializer serializer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (serializer == null)
            {
                throw new ArgumentNullException("serializer");
            }

            JObject jsonObject = new JObject();

            // Add discriminator field
            var polymorphicSerializer = serializer.Converters
                                        .FirstOrDefault(c =>
                                                        c.GetType().GetTypeInfo().IsGenericType&&
                                                        c.GetType().GetGenericTypeDefinition() == typeof(PolymorphicSerializeJsonConverter <>) &&
                                                        c.CanConvert(value.GetType())) as PolymorphicJsonConverter;

            if (polymorphicSerializer != null)
            {
                string typeName = value.GetType().Name;
                if (value.GetType().GetTypeInfo().GetCustomAttributes <JsonObjectAttribute>().Any())
                {
                    typeName = value.GetType().GetTypeInfo().GetCustomAttribute <JsonObjectAttribute>().Id;
                }
                jsonObject.Add(polymorphicSerializer.Discriminator, typeName);
            }

            JsonObjectContract contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(value.GetType());

            foreach (JsonProperty property in contract.Properties)
            {
                object memberValue = property.ValueProvider.GetValue(value);

                // Skipping properties with null value if NullValueHandling is set to Ignore
                if (serializer.NullValueHandling == NullValueHandling.Ignore &&
                    memberValue == null)
                {
                    continue;
                }

                // Skipping properties with JsonIgnore attribute, non-readable, and
                // ShouldSerialize returning false when set
                if (!property.Ignored && property.Readable &&
                    (property.ShouldSerialize == null || property.ShouldSerialize(memberValue)))
                {
                    string[] parentPath;
                    string   propertyName = property.GetPropertyName(out parentPath);

                    // Build hierarchy if necessary
                    JObject parentObject = jsonObject;
                    for (int i = 0; i < parentPath.Length; i++)
                    {
                        JObject childToken = parentObject[parentPath[i]] as JObject;
                        if (childToken == null)
                        {
                            parentObject[parentPath[i]] = new JObject();
                        }
                        parentObject = parentObject[parentPath[i]] as JObject;
                    }

                    parentObject[propertyName] = JToken.FromObject(memberValue, serializer);
                }
            }

            jsonObject.WriteTo(writer, serializer.Converters.ToArray());
        }
Example #23
0
        private async Task <PropertyModelInformation> GetPropertyModelInformation(ModelMetadata typeMetadataProperty, JsonObjectContract contract)
        {
            var jsonProperty = contract.Properties.Single(c => c.UnderlyingName == typeMetadataProperty.PropertyName);
            var propertyInfo = new PropertyModelInformation
            {
                Name            = typeMetadataProperty.PropertyName,
                DisplayName     = typeMetadataProperty.DisplayName,
                Description     = typeMetadataProperty.Description,
                PlaceHolderText = typeMetadataProperty.Placeholder,
                Key             = jsonProperty.PropertyName,
                Order           = typeMetadataProperty.Order,
                TypeName        = GetBuildInType(typeMetadataProperty.ModelType)
            };

            if (typeMetadataProperty.IsCollectionType)
            {
                propertyInfo.ElementModelInformation = new PropertyModelInformation
                {
                    PlaceHolderText = typeMetadataProperty.Placeholder,
                    TypeName        = GetBuildInType(typeMetadataProperty.ElementType)
                };
                propertyInfo.IsCollection = true;
            }
            if (_propertyMetadataProcessors != null)
            {
                foreach (var propertyMetadataProcessor in _propertyMetadataProcessors)
                {
                    if (propertyMetadataProcessor.CanProcess(typeMetadataProperty))
                    {
                        await propertyMetadataProcessor.ProcessProperty(typeMetadataProperty, propertyInfo);
                    }
                }
            }
            return(propertyInfo);
        }
 public virtual object Create(JsonReader reader, JsonSerializerReader internalReader, JsonObjectContract objectContract, string id, string unityGuid, Type objectType, out bool exit)
 {
     return(internalReader.CreateNewObject(reader, objectContract, null, null, id, unityGuid, out exit));
 }
 public static IDataTypeInfo Complex(DataType dataType, Type underlyingClrType, JsonObjectContract jsonContract) =>
 new ComplexDataTypeInfo(dataType, underlyingClrType, jsonContract);
        public override void WriteJson(JsonWriter writer, object value, JsonSerializerWriter internalWriter)
        {
            if (value == null || (value is UnityEngine.Object && value as UnityEngine.Object == null))
            {
                writer.WriteNull();
                return;
            }
            Type objectType = value.GetType();

            internalWriter._rootType  = objectType;
            internalWriter._rootLevel = internalWriter._serializeStack.Count + 1;
            JsonObjectContract contract = (JsonObjectContract)internalWriter.GetContractSafe(value);

            try
            {
                if (internalWriter.ShouldWriteReference(value, null, contract, null, null))
                {
                    internalWriter.WriteReference(writer, value);
                }
                else
                {
                    if (value == null)
                    {
                        writer.WriteNull();
                        return;
                    }
                    internalWriter.OnSerializing(writer, contract, value);

                    internalWriter._serializeStack.Add(value);

                    internalWriter.WriteObjectStart(writer, value, contract, null, null, null);

                    WriteProperties(contract, writer, value, objectType, internalWriter);

                    writer.WriteEndObject();

                    internalWriter._serializeStack.RemoveAt(internalWriter._serializeStack.Count - 1);

                    internalWriter.OnSerialized(writer, contract, value);
                }
            }
            catch (Exception ex)
            {
                if (internalWriter.IsErrorHandled(null, contract, null, null, writer.Path, ex))
                {
                    internalWriter.HandleError(writer, 0);
                }
                else
                {
                    // clear context in case serializer is being used inside a converter
                    // if the converter wraps the error then not clearing the context will cause this error:
                    // "Current error context error is different to requested error."
                    internalWriter.ClearErrorContext();
                    throw;
                }
            }
            finally
            {
                // clear root contract to ensure that if level was > 1 then it won't
                // accidently be used for non root values
                internalWriter._rootType = null;
            }
        }
Example #27
0
        protected void WriteReferenceObjectJson(JsonWriter writer, object value, JsonSerializer serializer, JsonObjectContract contract = null)
        {
            contract = contract ?? (JsonObjectContract)serializer.ContractResolver.ResolveContract(value.GetType());

            writer.WriteStartObject();

            //A "resource identifier object" MUST contain type and id members.
            writer.WritePropertyName(PropertyNames.Id);
            var idProp = contract.Properties.GetClosestMatchProperty(PropertyNames.Id);
            var idVal  = idProp?.ValueProvider?.GetValue(value) ?? string.Empty;

            serializer.Serialize(writer, idVal);

            writer.WritePropertyName(PropertyNames.Type);
            var typeProp = contract.Properties.GetClosestMatchProperty(PropertyNames.Type);
            var typeVal  = typeProp?.ValueProvider?.GetValue(value) ?? GenerateDefaultTypeName(value.GetType());

            serializer.Serialize(writer, typeVal);

            //we will only write the object to included if there are properties that have have data
            //that we cant include within the reference
            var willWriteObjectToIncluded = contract.Properties.Any(prop =>
            {
                //ignore id, type, meta and ignored properties
                if (prop.PropertyName == PropertyNames.Id ||
                    prop.PropertyName == PropertyNames.Type ||
                    prop.PropertyName == PropertyNames.Meta ||
                    prop.Ignored)
                {
                    return(false);
                }

                //ignore null properties
                var propValue = prop.ValueProvider.GetValue(value);
                if (propValue == null && serializer.NullValueHandling == NullValueHandling.Ignore)
                {
                    return(false);
                }

                //we have another property with a value
                return(true);
            });

            //typeically we would just write the meta in the included. But if we are not going to
            //have something in included we will write the meta inline here
            if (!willWriteObjectToIncluded)
            {
                var metaProp = contract.Properties.GetClosestMatchProperty(PropertyNames.Meta);
                var metaVal  = metaProp?.ValueProvider?.GetValue(value);
                if (metaVal != null)
                {
                    writer.WritePropertyName(PropertyNames.Meta);
                    serializer.Serialize(writer, metaVal);
                }
            }


            writer.WriteEndObject();


            if (willWriteObjectToIncluded)
            {
                var reference = IncludedReferenceResolver.GetReferenceValue(idVal.ToString(), typeVal.ToString());
                serializer.ReferenceResolver.AddReference(null, reference, value);
            }
        }
 public abstract void WriteProperties(JsonObjectContract contract, JsonWriter writer, object value, Type objectType, JsonSerializerWriter internalWriter);
Example #29
0
 public static bool IsInferrable(this JsonObjectContract objectContract)
 {
     return(!HttpTypeNames.Contains(objectContract.UnderlyingType.FullName));
 }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializerReader internalReader)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                if (!ReflectionUtils.IsNullable(objectType))
                {
                    throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
                }

                return(null);
            }
            if (objectType == null && existingValue != null)
            {
                objectType = existingValue.GetType();
            }

            JsonContract contract = internalReader.GetContractSafe(objectType);

            UnityEngine.Object unityObject = null;

            if (!reader.MoveToContent())
            {
                throw JsonSerializationException.Create(reader, "No JSON content found.");
            }
            if (reader.TokenType == JsonToken.Null)
            {
                return(null);
            }
            else if (reader.TokenType == JsonToken.StartObject)
            {
                string id;
                string unityGuid;
                Type   resolvedObjectType = objectType;

                if (internalReader.Serializer.MetadataPropertyHandling == MetadataPropertyHandling.Ignore)
                {
                    // don't look for metadata properties
                    reader.ReadAndAssert();
                    id        = null;
                    unityGuid = null;
                }
                else if (internalReader.Serializer.MetadataPropertyHandling == MetadataPropertyHandling.ReadAhead)
                {
                    JTokenReader tokenReader = reader as JTokenReader;
                    if (tokenReader == null)
                    {
                        JToken t = JToken.ReadFrom(reader);
                        tokenReader                        = (JTokenReader)t.CreateReader();
                        tokenReader.Culture                = reader.Culture;
                        tokenReader.DateFormatString       = reader.DateFormatString;
                        tokenReader.DateParseHandling      = reader.DateParseHandling;
                        tokenReader.DateTimeZoneHandling   = reader.DateTimeZoneHandling;
                        tokenReader.FloatParseHandling     = reader.FloatParseHandling;
                        tokenReader.SupportMultipleContent = reader.SupportMultipleContent;

                        // start
                        tokenReader.ReadAndAssert();

                        reader = tokenReader;
                    }

                    object newValue;
                    if (internalReader.ReadMetadataPropertiesToken(tokenReader, ref resolvedObjectType, ref contract, null, null, null, existingValue, out newValue, out id, out unityGuid, out unityObject))
                    {
                        if (SceneReferenceResolver.Current != null && !string.IsNullOrEmpty(unityGuid) && !AssetReferenceResolver.Current.Contains(unityGuid))
                        {
                            if (SceneReferenceResolver.Current.Contains(unityGuid))
                            {
                                SceneReferenceResolver.Current.Set(unityGuid, unityObject);
                            }
                            else
                            {
                                SceneReferenceResolver.Current.Add(unityGuid, unityObject);
                            }
                        }
                        if (unityObject != null)
                        {
                            return(unityObject);
                        }
                        return(newValue);
                    }
                }
                else
                {
                    reader.ReadAndAssert();
                    object newValue;
                    if (internalReader.ReadMetadataProperties(reader, ref resolvedObjectType, ref contract, null, null, null, existingValue, out newValue, out id, out unityGuid, out unityObject))
                    {
                        if (SceneReferenceResolver.Current != null && !string.IsNullOrEmpty(unityGuid) && !AssetReferenceResolver.Current.Contains(unityGuid))
                        {
                            if (SceneReferenceResolver.Current.Contains(unityGuid))
                            {
                                SceneReferenceResolver.Current.Set(unityGuid, unityObject);
                            }
                            else
                            {
                                SceneReferenceResolver.Current.Add(unityGuid, unityObject);
                            }
                        }
                        if (unityObject != null)
                        {
                            return(unityObject);
                        }
                        return(newValue);
                    }
                }

                if (internalReader.HasNoDefinedType(contract))
                {
                    return(internalReader.CreateJObject(reader));
                }

                bool createdFromNonDefaultCreator = false;
                JsonObjectContract objectContract = (JsonObjectContract)contract;
                object             targetObject;

                // check that if type name handling is being used that the existing value is compatible with the specified type
                if (existingValue != null && (resolvedObjectType == objectType || resolvedObjectType.IsAssignableFrom(existingValue.GetType())))
                {
                    targetObject = existingValue;
                }
                else if (unityObject != null)
                {
                    targetObject = unityObject;
                }
                else
                {
                    targetObject = Create(reader, internalReader, objectContract, id, unityGuid, objectType, out createdFromNonDefaultCreator);
                }

                if (SceneReferenceResolver.Current != null && !string.IsNullOrEmpty(unityGuid) && !AssetReferenceResolver.Current.Contains(unityGuid))
                {
                    if (SceneReferenceResolver.Current.Contains(unityGuid))
                    {
                        SceneReferenceResolver.Current.Set(unityGuid, (UnityEngine.Object)targetObject);
                    }
                    else
                    {
                        SceneReferenceResolver.Current.Add(unityGuid, (UnityEngine.Object)targetObject);
                    }
                }

                // don't populate if read from non-default creator because the object has already been read
                if (createdFromNonDefaultCreator)
                {
                    return(targetObject);
                }
                internalReader.OnDeserializing(reader, contract, targetObject);
                bool referenceAdded = false;
                if (id != null && targetObject != null)
                {
                    internalReader.AddReference(reader, id, targetObject);
                    referenceAdded = true;
                }
                targetObject = Populate(contract, reader, objectType, targetObject, internalReader);
                if (id != null && targetObject != null && !referenceAdded)
                {
                    internalReader.AddReference(reader, id, targetObject);
                }
                internalReader.OnDeserialized(reader, contract, targetObject);
                return(targetObject);
            }
            else
            {
                throw JsonSerializationException.Create(reader, "Unexpected initial token '{0}' when populating object. Expected JSON object.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
            }
        }
Example #31
0
 public static bool IsAmbiguous(this JsonObjectContract objectContract)
 {
     return(AmbiguousTypeNames.Contains(objectContract.UnderlyingType.FullName));
 }
 public ConstructorHandlingFallbackEventArgs(JsonObjectContract objectContract)
 {
     _objectContract = objectContract;
 }
        /// <summary>
        /// Add a projection to the query.
        /// </summary>
        /// <param name="expression">
        /// Select method call expression.
        /// </param>
        private void AddProjection(MethodCallExpression expression)
        {
            // We only support Select(x => ...) projections.  Anything else
            // will throw a NotSupportException.
            if (expression != null && expression.Arguments.Count == 2)
            {
                LambdaExpression projection = StripQuote(expression.Arguments[1]) as LambdaExpression;
                if (projection != null && projection.Parameters.Count == 1)
                {
                    // Compile the projection into a function that we can apply
                    // to the deserialized value to transform it accordingly.
                    this.queryDescription.Projections.Add(projection.Compile());

                    // We only need to capture the projection argument type and members for the
                    // very first projection.
                    if (this.queryDescription.ProjectionArgumentType == null)
                    {
                        // Store the type of the very first input to the projection as we'll
                        // need that for deserialization of values (since the
                        // projection will change the expected type of the data
                        // source)
                        this.queryDescription.ProjectionArgumentType = projection.Parameters[0].Type;

                        // Filter the selection down to just the values used by
                        // the projection
                        IExpressionUtility expressionUtility = Platform.Instance.ExpressionUtility;
                        foreach (MemberExpression memberExpression in expressionUtility.GetMemberExpressions(projection.Body))
                        {
                            // Ensure we only process members of the parameter
                            string memberName = FilterBuildingExpressionVisitor.GetTableMemberName(memberExpression, this.ContractResolver);
                            if (memberName != null)
                            {
                                queryDescription.Selection.Add(memberName);
                            }
                        }

                        //Make sure we also include all the members that would be
                        //required for deserialization
                        JsonContract       contract       = this.ContractResolver.ResolveContract(this.queryDescription.ProjectionArgumentType);
                        JsonObjectContract objectContract = contract as JsonObjectContract;
                        if (objectContract != null)
                        {
                            foreach (string propertyName in objectContract.Properties
                                     .Where(p => p.Required == Required.Always ||
                                            p.Required == Required.AllowNull)
                                     .Select(p => p.PropertyName))
                            {
                                if (!this.queryDescription.Selection.Contains(propertyName))
                                {
                                    this.queryDescription.Selection.Add(propertyName);
                                }
                            }
                        }
                    }

                    return;
                }
            }

            ThrowForUnsupportedException(expression);
        }
 static IEnumerable<JsonProperty> SerializableProperties(JsonObjectContract contract)
 {
     return contract.Properties.Where(p => !p.Ignored && p.Readable && p.Writable);
 }
        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;
        }
Example #36
0
 public JsonObjectContract CreateObjectContract(JsonObjectContract parentObjectContract, Type objectType)
 {
     parentObjectContract.ItemRequired = (Required)requiredLevel;
     return(parentObjectContract);
 }
        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;
        }
Example #38
0
        private JsonSchema GenerateInternal(Type type, Required valueRequired)
        {
            ValidationUtils.ArgumentNotNull(type, "type");

            string resolvedId = GetTypeId(type, false);
            string explicitId = GetTypeId(type, true);

            if (!string.IsNullOrEmpty(resolvedId))
            {
                JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
                if (resolvedSchema != null)
                {
                    return(resolvedSchema);
                }
            }

            // test for unresolved circular reference
            if (_stack.Any(tc => tc.Type == type))
            {
                throw new Exception("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
            }

            Push(new TypeSchema(type, new JsonSchema()));

            if (explicitId != null)
            {
                CurrentSchema.Id = explicitId;
            }

            CurrentSchema.Title       = GetTitle(type);
            CurrentSchema.Description = GetDescription(type);

            if (CollectionUtils.IsDictionaryType(type))
            {
                // TODO: include null
                CurrentSchema.Type = JsonSchemaType.Object;

                Type keyType;
                Type valueType;
                ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);

                if (keyType != null)
                {
                    // can be converted to a string
                    if (typeof(IConvertible).IsAssignableFrom(keyType))
                    {
                        CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default);
                    }
                }
            }
            else if (CollectionUtils.IsCollectionType(type))
            {
                // TODO: include null
                CurrentSchema.Type = JsonSchemaType.Array;

                CurrentSchema.Id = GetTypeId(type, false);

                JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
                bool allowNullItem = (arrayAttribute != null) ? arrayAttribute.AllowNullItems : false;

                Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                if (collectionItemType != null)
                {
                    CurrentSchema.Items = new List <JsonSchema>();
                    CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default));
                }
            }
            else
            {
                CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);

                if (HasFlag(CurrentSchema.Type, JsonSchemaType.Object))
                {
                    CurrentSchema.Id = GetTypeId(type, false);

                    JsonObjectContract contract = ContractResolver.ResolveContract(type) as JsonObjectContract;

                    if (contract == null)
                    {
                        throw new Exception("Could not resolve contract for '{0}'.".FormatWith(CultureInfo.InvariantCulture, type));
                    }

                    CurrentSchema.Properties = new Dictionary <string, JsonSchema>();
                    foreach (JsonProperty property in contract.Properties)
                    {
                        if (!property.Ignored)
                        {
                            JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required);

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

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

                    if (type.IsSealed)
                    {
                        CurrentSchema.AllowAdditionalProperties = false;
                    }
                }
                else if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum && !type.IsDefined(typeof(FlagsAttribute), true))
                {
                    CurrentSchema.Enum    = new List <JToken>();
                    CurrentSchema.Options = new Dictionary <JToken, string>();

                    EnumValues <long> enumValues = EnumUtils.GetNamesAndValues <long>(type);
                    foreach (EnumValue <long> enumValue in enumValues)
                    {
                        JToken value = JToken.FromObject(enumValue.Value);

                        CurrentSchema.Enum.Add(value);
                        CurrentSchema.Options.Add(value, enumValue.Name);
                    }
                }
            }

            return(Pop().Schema);
        }
        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();
            }
        }
Example #40
0
 bool ConstructorParameterAlreadyExists(JsonObjectContract contract, JsonProperty property)
 {
     return(contract.CreatorParameters.Any(p => p.PropertyName == property.PropertyName && p.PropertyType == property.PropertyType));
 }
        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);
        }
        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);
        }