Exemplo n.º 1
0
        public void InitializeRoot(Type type, JsonSerializerOptions options)
        {
            JsonClassInfo jsonClassInfo = options.GetOrAddClass(type);

            Debug.Assert(jsonClassInfo.ClassType != ClassType.Invalid);

            Current.JsonClassInfo = jsonClassInfo;

            // The initial JsonPropertyInfo will be used to obtain the converter.
            Current.JsonPropertyInfo = jsonClassInfo.PolicyProperty !;

            if (options.ReferenceHandling.ShouldReadPreservedReferences())
            {
                ReferenceResolver = new DefaultReferenceResolver(writing: false);
            }
        }
Exemplo n.º 2
0
        public void Initialize(Type type, JsonSerializerOptions options, bool supportContinuation)
        {
            JsonClassInfo jsonClassInfo = options.GetOrAddClass(type);

            Current.JsonClassInfo = jsonClassInfo;

            // The initial JsonPropertyInfo will be used to obtain the converter.
            Current.JsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo;

            if (options.ReferenceHandling.ShouldReadPreservedReferences())
            {
                ReferenceResolver = new DefaultReferenceResolver(writing: false);
            }

            SupportContinuation = supportContinuation;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Initialize the state without delayed initialization of the JsonClassInfo.
        /// </summary>
        public void Initialize(Type type, JsonSerializerOptions options, bool supportContinuation)
        {
            JsonClassInfo jsonClassInfo = options.GetOrAddClass(type);

            Current.JsonClassInfo = jsonClassInfo;

            if ((jsonClassInfo.ClassType & (ClassType.Enumerable | ClassType.Dictionary)) == 0)
            {
                Current.DeclaredJsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo;
            }

            if (options.ReferenceHandling.ShouldWritePreservedReferences())
            {
                ReferenceResolver = new DefaultReferenceResolver(writing: true);
            }

            SupportContinuation = supportContinuation;
        }
Exemplo n.º 4
0
        public void Initialize(Type type, JsonSerializerOptions options, bool supportContinuation)
        {
            JsonClassInfo jsonClassInfo = options.GetOrAddClass(type);

            Current.JsonClassInfo = jsonClassInfo;

            // The initial JsonPropertyInfo will be used to obtain the converter.
            Current.JsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo;

            bool preserveReferences = options.ReferenceHandler != null;

            if (preserveReferences)
            {
                ReferenceResolver = options.ReferenceHandler !.CreateResolver(writing: false);
            }

            SupportContinuation = supportContinuation;
            UseFastPath         = !supportContinuation && !preserveReferences;
        }
Exemplo n.º 5
0
 public void Initialize(Type type, JsonSerializerOptions options)
 {
     JsonClassInfo = options.GetOrAddClass(type);
     if (JsonClassInfo.ClassType == ClassType.Value || JsonClassInfo.ClassType == ClassType.Enumerable || JsonClassInfo.ClassType == ClassType.Dictionary)
     {
         JsonPropertyInfo = JsonClassInfo.GetPolicyProperty();
     }
     else if (JsonClassInfo.ClassType == ClassType.IDictionaryConstructible)
     {
         JsonPropertyInfo           = JsonClassInfo.GetPolicyProperty();
         IsIDictionaryConstructible = true;
     }
     else if (JsonClassInfo.ClassType == ClassType.KeyValuePair)
     {
         JsonPropertyInfo = JsonClassInfo.GetPolicyPropertyOfKeyValuePair();
         // Advance to the next property, since the first one is the KeyValuePair type itself,
         // not its first property (Key or Value).
         PropertyIndex++;
     }
 }
Exemplo n.º 6
0
        /// <summary>
        /// Initialize the state without delayed initialization of the JsonClassInfo.
        /// </summary>
        public void Initialize(Type type, JsonSerializerOptions options, bool supportContinuation)
        {
            JsonClassInfo jsonClassInfo = options.GetOrAddClass(type);

            Current.JsonClassInfo = jsonClassInfo;

            if ((jsonClassInfo.ClassType & (ClassType.Enumerable | ClassType.Dictionary)) == 0)
            {
                Current.DeclaredJsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo;
            }

            bool preserveReferences = options.ReferenceHandler != null;

            if (preserveReferences)
            {
                ReferenceResolver = options.ReferenceHandler !.CreateResolver(writing: true);
            }

            SupportContinuation = supportContinuation;
        }
Exemplo n.º 7
0
 public void Initialize(Type type, JsonSerializerOptions options)
 {
     JsonClassInfo = options.GetOrAddClass(type);
     InitializeJsonPropertyInfo();
 }
        private static void HandleStartDictionary(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state)
        {
            Debug.Assert(!state.Current.IsProcessingEnumerable);

            JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo;

            if (jsonPropertyInfo == null)
            {
                jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootObject(options);
            }

            Debug.Assert(jsonPropertyInfo != null);

            // A nested object or dictionary so push new frame.
            if (state.Current.PropertyInitialized)
            {
                state.Push();
                state.Current.JsonClassInfo = jsonPropertyInfo.ElementClassInfo;
                state.Current.InitializeJsonPropertyInfo();
                state.Current.PropertyInitialized = true;

                ClassType classType = state.Current.JsonClassInfo.ClassType;
                if (classType == ClassType.Value &&
                    jsonPropertyInfo.ElementClassInfo.Type != typeof(object) &&
                    jsonPropertyInfo.ElementClassInfo.Type != typeof(JsonElement))
                {
                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(state.Current.JsonClassInfo.Type, reader, state.JsonPath);
                }

                JsonClassInfo classInfo = state.Current.JsonClassInfo;

                if (state.Current.IsProcessingIDictionaryConstructibleOrKeyValuePair)
                {
                    state.Current.TempDictionaryValues = (IDictionary)classInfo.CreateObject();
                }
                else
                {
                    if (classInfo.CreateObject == null)
                    {
                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(classInfo.Type, reader, state.JsonPath);
                        return;
                    }
                    state.Current.ReturnValue = classInfo.CreateObject();
                }
                return;
            }

            state.Current.PropertyInitialized = true;

            if (state.Current.IsProcessingIDictionaryConstructibleOrKeyValuePair)
            {
                JsonClassInfo dictionaryClassInfo = options.GetOrAddClass(jsonPropertyInfo.RuntimePropertyType);
                state.Current.TempDictionaryValues = (IDictionary)dictionaryClassInfo.CreateObject();
            }
            // Else if current property is already set (from a constructor, for example), leave as-is.
            else if (jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue) == null)
            {
                // Create the dictionary.
                JsonClassInfo dictionaryClassInfo = jsonPropertyInfo.RuntimeClassInfo;
                IDictionary   value = (IDictionary)dictionaryClassInfo.CreateObject();

                if (value != null)
                {
                    if (state.Current.ReturnValue != null)
                    {
                        state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value);
                    }
                    else
                    {
                        // A dictionary is being returned directly, or a nested dictionary.
                        state.Current.SetReturnValue(value);
                    }
                }
            }
        }
Exemplo n.º 9
0
        private static void HandleStartDictionary(JsonSerializerOptions options, ref ReadStack state)
        {
            Debug.Assert(!state.Current.IsProcessingEnumerable());

            JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo;

            if (jsonPropertyInfo == null)
            {
                jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootObject(options);
            }

            Debug.Assert(jsonPropertyInfo != null);

            // A nested object or dictionary so push new frame.
            if (state.Current.CollectionPropertyInitialized)
            {
                state.Push();
                state.Current.JsonClassInfo = jsonPropertyInfo.ElementClassInfo;
                state.Current.InitializeJsonPropertyInfo();
                state.Current.CollectionPropertyInitialized = true;

                ClassType classType = state.Current.JsonClassInfo.ClassType;
                if (classType == ClassType.Value)
                {
                    Type elementClassInfoType = jsonPropertyInfo.ElementClassInfo.Type;
                    if (elementClassInfoType != typeof(object) && elementClassInfoType != typeof(JsonElement))
                    {
                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(state.Current.JsonClassInfo.Type);
                    }
                }

                JsonClassInfo classInfo = state.Current.JsonClassInfo;

                if (state.Current.IsProcessingIDictionaryConstructible())
                {
                    state.Current.TempDictionaryValues = (IDictionary)classInfo.CreateConcreteDictionary();
                }
                else
                {
                    if (classInfo.CreateObject == null)
                    {
                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(classInfo.Type);
                        return;
                    }
                    state.Current.ReturnValue = classInfo.CreateObject();
                }

                return;
            }

            state.Current.CollectionPropertyInitialized = true;

            if (state.Current.IsProcessingIDictionaryConstructible())
            {
                JsonClassInfo dictionaryClassInfo;
                if (jsonPropertyInfo.DeclaredPropertyType == jsonPropertyInfo.ImplementedPropertyType)
                {
                    dictionaryClassInfo = options.GetOrAddClass(jsonPropertyInfo.RuntimePropertyType);
                }
                else
                {
                    dictionaryClassInfo = options.GetOrAddClass(jsonPropertyInfo.DeclaredPropertyType);
                }

                state.Current.TempDictionaryValues = (IDictionary)dictionaryClassInfo.CreateConcreteDictionary();
            }
            else
            {
                // Create the dictionary.
                JsonClassInfo dictionaryClassInfo = jsonPropertyInfo.RuntimeClassInfo;
                IDictionary   value = (IDictionary)dictionaryClassInfo.CreateObject();

                if (value != null)
                {
                    if (state.Current.ReturnValue != null)
                    {
                        state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value);
                    }
                    else
                    {
                        // A dictionary is being returned directly, or a nested dictionary.
                        state.Current.SetReturnValue(value);
                    }
                }
            }
        }
Exemplo n.º 10
0
        internal JsonClassInfo(Type type, JsonSerializerOptions options)
        {
            Type      = type;
            Options   = options;
            ClassType = GetClassType(type, options);

            CreateObject = options.MemberAccessorStrategy.CreateConstructor(type);

            // Ignore properties on enumerable.
            switch (ClassType)
            {
            case ClassType.Object:
            {
                PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

                Dictionary <string, JsonPropertyInfo> cache = CreatePropertyCache(properties.Length);

                foreach (PropertyInfo propertyInfo in properties)
                {
                    // Ignore indexers
                    if (propertyInfo.GetIndexParameters().Length > 0)
                    {
                        continue;
                    }

                    // For now we only support public getters\setters
                    if (propertyInfo.GetMethod?.IsPublic == true ||
                        propertyInfo.SetMethod?.IsPublic == true)
                    {
                        JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, type, options);
                        Debug.Assert(jsonPropertyInfo != null);

                        // If the JsonPropertyNameAttribute or naming policy results in collisions, throw an exception.
                        if (!JsonHelpers.TryAdd(cache, jsonPropertyInfo.NameAsString, jsonPropertyInfo))
                        {
                            JsonPropertyInfo other = cache[jsonPropertyInfo.NameAsString];

                            if (other.ShouldDeserialize == false && other.ShouldSerialize == false)
                            {
                                // Overwrite the one just added since it has [JsonIgnore].
                                cache[jsonPropertyInfo.NameAsString] = jsonPropertyInfo;
                            }
                            else if (jsonPropertyInfo.ShouldDeserialize == true || jsonPropertyInfo.ShouldSerialize == true)
                            {
                                ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(this, jsonPropertyInfo);
                            }
                            // else ignore jsonPropertyInfo since it has [JsonIgnore].
                        }
                    }
                }

                if (DetermineExtensionDataProperty(cache))
                {
                    // Remove from cache since it is handled independently.
                    cache.Remove(DataExtensionProperty.NameAsString);
                }

                // Set as a unit to avoid concurrency issues.
                PropertyCache = cache;
            }
            break;

            case ClassType.Enumerable:
            case ClassType.Dictionary:
            {
                // Add a single property that maps to the class type so we can have policies applied.
                AddPolicyProperty(type, options);

                Type objectType;
                if (IsNativelySupportedCollection(type))
                {
                    // Use the type from the property policy to get any late-bound concrete types (from an interface like IDictionary).
                    objectType = PolicyProperty.RuntimePropertyType;
                }
                else
                {
                    // We need to create the declared instance for types implementing natively supported collections.
                    objectType = PolicyProperty.DeclaredPropertyType;
                }

                CreateObject = options.MemberAccessorStrategy.CreateConstructor(objectType);

                // Create a ClassInfo that maps to the element type which is used for (de)serialization and policies.
                Type elementType = GetElementType(type, parentType: null, memberInfo: null, options: options);
                ElementClassInfo = options.GetOrAddClass(elementType);
            }
            break;

            case ClassType.IDictionaryConstructible:
            {
                // Add a single property that maps to the class type so we can have policies applied.
                AddPolicyProperty(type, options);

                Type elementType = GetElementType(type, parentType: null, memberInfo: null, options: options);

                CreateConcreteDictionary = options.MemberAccessorStrategy.CreateConstructor(
                    typeof(Dictionary <,>).MakeGenericType(typeof(string), elementType));

                CreateObject = options.MemberAccessorStrategy.CreateConstructor(PolicyProperty.DeclaredPropertyType);

                // Create a ClassInfo that maps to the element type which is used for (de)serialization and policies.
                ElementClassInfo = options.GetOrAddClass(elementType);
            }
            break;

            case ClassType.Value:
                // Add a single property that maps to the class type so we can have policies applied.
                AddPolicyProperty(type, options);
                break;

            case ClassType.Unknown:
                // Add a single property that maps to the class type so we can have policies applied.
                AddPolicyProperty(type, options);
                PropertyCache = new Dictionary <string, JsonPropertyInfo>();
                break;

            default:
                Debug.Fail($"Unexpected class type: {ClassType}");
                break;
            }
        }
Exemplo n.º 11
0
        internal JsonClassInfo(Type type, JsonSerializerOptions options)
        {
            Type      = type;
            ClassType = GetClassType(type, options);

            CreateObject = options.ClassMaterializerStrategy.CreateConstructor(type);

            // Ignore properties on enumerable.
            switch (ClassType)
            {
            case ClassType.Object:
            {
                var propertyNames = new HashSet <string>(StringComparer.Ordinal);

                foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    // Ignore indexers
                    if (propertyInfo.GetIndexParameters().Length > 0)
                    {
                        continue;
                    }

                    // For now we only support public getters\setters
                    if (propertyInfo.GetMethod?.IsPublic == true ||
                        propertyInfo.SetMethod?.IsPublic == true)
                    {
                        JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, type, options);

                        Debug.Assert(jsonPropertyInfo.NameUsedToCompareAsString != null);

                        // If the JsonPropertyNameAttribute or naming policy results in collisions, throw an exception.
                        if (!propertyNames.Add(jsonPropertyInfo.NameUsedToCompareAsString))
                        {
                            ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(this, jsonPropertyInfo);
                        }

                        jsonPropertyInfo.ClearUnusedValuesAfterAdd();
                    }
                }

                DetermineExtensionDataProperty();
            }
            break;

            case ClassType.Enumerable:
            case ClassType.Dictionary:
            {
                // Add a single property that maps to the class type so we can have policies applied.
                JsonPropertyInfo policyProperty = AddPolicyProperty(type, options);

                // Use the type from the property policy to get any late-bound concrete types (from an interface like IDictionary).
                CreateObject = options.ClassMaterializerStrategy.CreateConstructor(policyProperty.RuntimePropertyType);

                // Create a ClassInfo that maps to the element type which is used for (de)serialization and policies.
                Type elementType = GetElementType(type, parentType: null, memberInfo: null, options: options);
                ElementClassInfo = options.GetOrAddClass(elementType);
            }
            break;

            case ClassType.IDictionaryConstructible:
            {
                // Add a single property that maps to the class type so we can have policies applied.
                AddPolicyProperty(type, options);

                Type elementType = GetElementType(type, parentType: null, memberInfo: null, options: options);

                CreateObject = options.ClassMaterializerStrategy.CreateConstructor(
                    typeof(Dictionary <,>).MakeGenericType(typeof(string), elementType));

                // Create a ClassInfo that maps to the element type which is used for (de)serialization and policies.
                ElementClassInfo = options.GetOrAddClass(elementType);
            }
            break;

            case ClassType.Value:
            case ClassType.Unknown:
                // Add a single property that maps to the class type so we can have policies applied.
                AddPolicyProperty(type, options);
                break;

            default:
                Debug.Fail($"Unexpected class type: {ClassType}");
                break;
            }
        }
Exemplo n.º 12
0
        internal JsonClassInfo(Type type, JsonSerializerOptions options)
        {
            Type      = type;
            ClassType = GetClassType(type);

            CreateObject = options.ClassMaterializerStrategy.CreateConstructor(type);

            // Ignore properties on enumerable.
            switch (ClassType)
            {
            case ClassType.Object:
            {
                var propertyNames = new HashSet <string>(StringComparer.Ordinal);

                foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    // Ignore indexers
                    if (propertyInfo.GetIndexParameters().Length > 0)
                    {
                        continue;
                    }

                    // For now we only support public getters\setters
                    if (propertyInfo.GetMethod?.IsPublic == true ||
                        propertyInfo.SetMethod?.IsPublic == true)
                    {
                        JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, type, options);

                        Debug.Assert(jsonPropertyInfo.NameUsedToCompareAsString != null);

                        // If the JsonPropertyNameAttribute or naming policy results in collisions, throw an exception.
                        if (!propertyNames.Add(jsonPropertyInfo.NameUsedToCompareAsString))
                        {
                            ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(this, jsonPropertyInfo);
                        }

                        jsonPropertyInfo.ClearUnusedValuesAfterAdd();
                    }
                }

                DetermineExtensionDataProperty();
            }
            break;

            case ClassType.Enumerable:
            case ClassType.Dictionary:
            {
                // Add a single property that maps to the class type so we can have policies applied.
                JsonPropertyInfo policyProperty = AddPolicyProperty(type, options);

                // Use the type from the property policy to get any late-bound concrete types (from an interface like IDictionary).
                CreateObject = options.ClassMaterializerStrategy.CreateConstructor(policyProperty.RuntimePropertyType);

                // Create a ClassInfo that maps to the element type which is used for (de)serialization and policies.
                Type elementType = GetElementType(type, parentType: null, memberInfo: null);
                ElementClassInfo = options.GetOrAddClass(elementType);
            }
            break;

            case ClassType.IDictionaryConstructible:
            {
                // Add a single property that maps to the class type so we can have policies applied.
                AddPolicyProperty(type, options);

                Type elementType = GetElementType(type, parentType: null, memberInfo: null);

                CreateObject = options.ClassMaterializerStrategy.CreateConstructor(
                    typeof(Dictionary <,>).MakeGenericType(typeof(string), elementType));

                // Create a ClassInfo that maps to the element type which is used for (de)serialization and policies.
                ElementClassInfo = options.GetOrAddClass(elementType);
            }
            break;

            // TODO: Utilize converter mechanism to handle (de)serialization of KeyValuePair
            // when it goes through: https://github.com/dotnet/corefx/issues/36639.
            case ClassType.KeyValuePair:
            {
                // For deserialization, we treat it as ClassType.IDictionaryConstructible so we can parse it like a dictionary
                // before using converter-like logic to create a KeyValuePair instance.

                // Add a single property that maps to the class type so we can have policies applied.
                AddPolicyProperty(type, options);

                Type elementType = GetElementType(type, parentType: null, memberInfo: null);

                // Make this Dictionary<string, object> to accomodate input of form {"Key": "MyKey", "Value": 1}.
                CreateObject = options.ClassMaterializerStrategy.CreateConstructor(typeof(Dictionary <string, object>));

                // Create a ClassInfo that maps to the element type which is used for deserialization and policies.
                ElementClassInfo = options.GetOrAddClass(elementType);

                // For serialization, we treat it like ClassType.Object to utilize the public getters.

                // Add Key property
                PropertyInfo     propertyInfo     = type.GetProperty("Key", BindingFlags.Public | BindingFlags.Instance);
                JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, type, options);
                Debug.Assert(jsonPropertyInfo.NameUsedToCompareAsString != null);
                jsonPropertyInfo.ClearUnusedValuesAfterAdd();

                // Add Value property.
                propertyInfo     = type.GetProperty("Value", BindingFlags.Public | BindingFlags.Instance);
                jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, type, options);
                Debug.Assert(jsonPropertyInfo.NameUsedToCompareAsString != null);
                jsonPropertyInfo.ClearUnusedValuesAfterAdd();
            }
            break;

            case ClassType.Value:
            case ClassType.Unknown:
                // Add a single property that maps to the class type so we can have policies applied.
                AddPolicyProperty(type, options);
                break;

            default:
                Debug.Fail($"Unexpected class type: {ClassType}");
                break;
            }
        }