public override JsonMergePatch <T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var model = new JsonMergePatch <T>(); while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return(model); // success: end of object } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException(); // fail: did not pass through previous property value } var key = reader.GetString(); if (string.IsNullOrWhiteSpace(key) || !_members.TryGetValue(key, out var member) || !member.CanRead) { continue; } var value = JsonSerializer.Deserialize(ref reader, member.Type, options); model.TrySetPropertyValue(key, value); } // fail: passed through JsonTokenType.EndObject throw new JsonException(); }
internal static void WriteInner(AccessorMembers members, IReadAccessor reader, Utf8JsonWriter writer, IShaped value, JsonSerializerOptions options) { if (value.Body != null) { foreach (var field in value.Fields) { if (!members.TryGetValue(field, out var member)) { continue; } if (!member.CanRead) { continue; } // key: var propertyName = options.PropertyNamingPolicy?.ConvertName(member.Name) ?? member.Name; writer.WritePropertyName(propertyName); // value (can be null): reader.TryGetValue(value.Body, member.Name, out var item); JsonSerializer.Serialize(writer, item, options); } } }
public override ShapedData <T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartObject) { throw new JsonException(); } T data; if (typeof(T).ImplementsGeneric(typeof(Many <>))) { // FIXME: Instancing can't handle nested generic types, so we have to use manual reflection here // until it is resolved. var underlyingType = typeof(T).GetGenericArguments()[0]; var enumerableType = typeof(List <>).MakeGenericType(underlyingType); var enumerable = Activator.CreateInstance(enumerableType); data = (T)(Activator.CreateInstance(typeof(T), enumerable) ?? throw new NullReferenceException()); } else { data = Instancing.CreateInstance <T>(); } while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return(new ShapedData <T>(data)); // success: end of object } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException(); // fail: did not pass through previous property value } var key = reader.GetString(); if (string.IsNullOrWhiteSpace(key) || !_members.TryGetValue(key, out var member) || !member.CanWrite) { continue; } var value = JsonSerializer.Deserialize(ref reader, member.Type, options); if (!_writer.TrySetValue(data, key, value !)) { throw new JsonException(); } } // fail: passed through JsonTokenType.EndObject throw new JsonException(); }
public static IReadOnlyDictionary <AccessorMember, object> ToHash(this AccessorMembers members, object @object, string[] fields, IDataInfoProvider provider, IEnumerable <IFieldTransform> transforms) { var accessor = ReadAccessor.Create(@object, members.Types, members.Scope); var usePool = fields.Length > 0 || provider != null; // FIXME: remove AsList call var include = usePool ? Pooling.ListPool <AccessorMember> .Get() : members.AsList(); try { if (fields.Length > 0) { foreach (var field in fields) { if (members.TryGetValue(field, out var member) && !IsIgnored(provider, member) && IsSaved(provider, member)) { include.Add(member); } } } else { foreach (var member in members) { if (IsIgnored(provider, member)) { include.Remove(member); continue; } if (IsSaved(provider, member)) { include.Add(member); } } } return(members.ToDictionary(k => k, v => ResolveValue(@object, transforms, accessor, v))); } finally { if (usePool) { Pooling.ListPool <AccessorMember> .Return((List <AccessorMember>) include); } } }