コード例 #1
0
        private static void HandleStartArray(
            JsonSerializerOptions options,
            ref Utf8JsonReader reader,
            ref ReadStack state)
        {
            JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo;

            if (state.Current.SkipProperty)
            {
                // The array is not being applied to the object.
                state.Push();
                state.Current.Drain = true;
                return;
            }

            if (jsonPropertyInfo == null)
            {
                jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootObject(options);
            }
            else if (state.Current.JsonClassInfo.ClassType == ClassType.Unknown)
            {
                jsonPropertyInfo = state.Current.JsonClassInfo.CreatePolymorphicProperty(jsonPropertyInfo, typeof(object), options);
            }

            // Verify that we don't have a multidimensional array.
            Type arrayType = jsonPropertyInfo.RuntimePropertyType;

            if (!typeof(IEnumerable).IsAssignableFrom(arrayType) || (arrayType.IsArray && arrayType.GetArrayRank() > 1))
            {
                ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(arrayType, reader, state.JsonPath);
            }

            Debug.Assert(state.Current.IsProcessingEnumerableOrDictionary);

            if (state.Current.CollectionPropertyInitialized)
            {
                // A nested json array so push a new stack frame.
                Type elementType = jsonPropertyInfo.ElementClassInfo.Type;

                state.Push();
                state.Current.Initialize(elementType, options);
            }

            state.Current.CollectionPropertyInitialized = true;
            jsonPropertyInfo = state.Current.JsonPropertyInfo;

            if (state.Current.JsonClassInfo.ClassType == ClassType.Value)
            {
                state.Current.JsonPropertyInfo.Read(JsonTokenType.StartObject, ref state, ref reader);
            }
            else
            {
                // If current property is already set (from a constructor, for example) leave as-is.
                if (jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue) == null)
                {
                    // Create the enumerable.
                    object value = ReadStackFrame.CreateEnumerableValue(ref reader, ref state, options);

                    // If value is not null, then we don't have a converter so apply the value.
                    if (value != null)
                    {
                        if (state.Current.ReturnValue != null)
                        {
                            state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value);
                        }
                        else
                        {
                            // Primitive arrays being returned without object
                            state.Current.SetReturnValue(value);
                        }
                    }
                }
            }
        }
コード例 #2
0
        private static void HandleStartArray(JsonSerializerOptions options, ref ReadStack state)
        {
            if (state.Current.SkipProperty)
            {
                // The array is not being applied to the object.
                state.Push();
                state.Current.Drain = true;
                return;
            }
            Debug.Assert(state.Current.JsonClassInfo != null);
            JsonPropertyInfo?jsonPropertyInfo = state.Current.JsonPropertyInfo;

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

            // Verify that we are processing a valid enumerable or dictionary.
            if (((ClassType.Enumerable | ClassType.Dictionary) & jsonPropertyInfo.ClassType) == 0)
            {
                ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(jsonPropertyInfo.RuntimePropertyType);
            }

            if (state.Current.CollectionPropertyInitialized)
            {
                // An array nested in a dictionary or array, so push a new stack frame.
                Type elementType = jsonPropertyInfo.ElementClassInfo !.Type;

                state.Push();
                state.Current.Initialize(elementType, options);
            }

            state.Current.CollectionPropertyInitialized = true;

            // The current JsonPropertyInfo will be null if the current type is not one of
            // ClassType.Value | ClassType.Enumerable | ClassType.Dictionary.
            // We should not see ClassType.Value here because we handle it on a different code
            // path invoked in the main read loop.
            // Only ClassType.Enumerable is valid here since we just saw a StartArray token.
            if (state.Current.JsonPropertyInfo == null ||
                state.Current.JsonPropertyInfo.ClassType != ClassType.Enumerable)
            {
                ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(state.Current.JsonClassInfo.Type);
            }

            // Set or replace the existing enumerable value.
            object?value = ReadStackFrame.CreateEnumerableValue(ref state);

            // If value is not null, then we don't have a converter so apply the value.
            if (value != null)
            {
                state.Current.DetermineEnumerablePopulationStrategy(value);

                if (state.Current.ReturnValue != null)
                {
                    state.Current.JsonPropertyInfo !.SetValueAsObject(state.Current.ReturnValue, value);
                }
                else
                {
                    state.Current.ReturnValue = value;
                }
            }
        }
コード例 #3
0
        private static void HandleStartArray(
            JsonSerializerOptions options,
            ref Utf8JsonReader reader,
            ref ReadStack state)
        {
            if (state.Current.SkipProperty)
            {
                // The array is not being applied to the object.
                state.Push();
                state.Current.Drain = true;
                return;
            }

            JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo;

            if (jsonPropertyInfo == null)
            {
                jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootObject(options);
            }
            else if (state.Current.JsonClassInfo.ClassType == ClassType.Unknown)
            {
                jsonPropertyInfo = state.Current.JsonClassInfo.CreatePolymorphicProperty(jsonPropertyInfo, typeof(object), options);
            }

            // Verify that we have a valid enumerable.
            Type arrayType = jsonPropertyInfo.RuntimePropertyType;

            if (!typeof(IEnumerable).IsAssignableFrom(arrayType))
            {
                ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(arrayType);
            }

            Debug.Assert(state.Current.IsProcessingCollection());

            if (state.Current.CollectionPropertyInitialized)
            {
                // A nested json array so push a new stack frame.
                Type elementType = jsonPropertyInfo.ElementClassInfo.Type;

                state.Push();
                state.Current.Initialize(elementType, options);
            }

            state.Current.CollectionPropertyInitialized = true;

            // We should not be processing custom converters here (converters are of ClassType.Value).
            Debug.Assert(state.Current.JsonClassInfo.ClassType != ClassType.Value);

            // Set or replace the existing enumerable value.
            object value = ReadStackFrame.CreateEnumerableValue(ref reader, ref state);

            // If value is not null, then we don't have a converter so apply the value.
            if (value != null)
            {
                if (state.Current.ReturnValue != null)
                {
                    state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value);
                }
                else
                {
                    // Primitive arrays being returned without object
                    state.Current.SetReturnValue(value);
                }
            }
        }