Esempio n. 1
0
        public static object ReadObject(
            JsonElement obj,
            IOpenApiType itemType,
            Type itemClrType,
            IOpenApiTypeHandler typeHandler,
            bool objectAsDelta = false)
        {
            if (itemType == null)
            {
                throw new SerializationException("Cannot deserialize unknown type.");
            }

            var properties = obj.EnumerateObject().ToDictionary(p => p.Name, p => p.Value);

            if (properties.TryGetValue("@odata.type", out var type) && type.ValueKind == JsonValueKind.String)
            {
                var typeName   = type.GetString();
                var actualType = typeHandler.ResolveType(typeName);
                if (actualType == null)
                {
                    throw new SerializationException($"No type with identifier '{typeName}' found");
                }

                if (!itemClrType.IsAssignableFrom(actualType.ClrType))
                {
                    throw new SerializationException($"Type '{typeName}' is not assignable to '{itemType.JsonName}'");
                }

                itemType    = actualType;
                itemClrType = actualType.ClrType;
            }

            var instance = objectAsDelta
                ? Activator.CreateInstance(typeof(Delta <>).MakeGenericType(itemClrType))
                : Activator.CreateInstance(itemClrType);

            foreach (var member in properties)
            {
                if (itemType.TryGetProperty(member.Key, out var property))
                {
                    var propertyType = typeHandler.ResolveType(property.ClrProperty.PropertyType);

                    var value = ReadValue(member.Value,
                                          propertyType,
                                          property.ClrProperty.PropertyType,
                                          typeHandler,
                                          objectAsDelta);
                    // TODO: check for components in the model binding area which help us here
                    // many conversions (string -> enum,date,timespan) etc. do not work like this.
                    property.SetValue(instance, value);
                }
                else
                {
                    // TODO: how do we want to treat unknown props? fail or ignore?
                }
            }

            return(instance);
        }
Esempio n. 2
0
        private object ReadObject(
            ref Utf8JsonReader reader,
            IOpenApiType itemType,
            Type itemClrType,
            JsonSerializerOptions options)
        {
            if (itemType == null)
            {
                throw new JsonException($"Cannot deserialize unknown type.");
            }

            // TODO: better object creation, and polymorphism handling!
            var instance = Activator.CreateInstance(itemClrType);

            while (reader.Read())
            {
                if (reader.TokenType == JsonTokenType.EndObject)
                {
                    return(instance);
                }

                if (reader.TokenType != JsonTokenType.PropertyName)
                {
                    throw new JsonException($"Unexpected JSON Token {reader.TokenType}.");
                }

                var propertyName = reader.GetString();

                if (itemType.TryGetProperty(propertyName, out var property))
                {
                    var propertyType = _typeHandler.ResolveType(property.ClrProperty.PropertyType);
                    var value        = ReadValue(ref reader, propertyType, property.ClrProperty.PropertyType, options);
                    property.SetValue(instance, value);
                }
                else
                {
                    throw new JsonException($"Unexpected property {propertyName}.");
                }
            }

            throw new JsonException($"Unexpected end of stream.");
        }