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