From d62bdfc637634b6d878e1745b8e4c34889e848a7 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 22 Mar 2024 23:04:07 +0100 Subject: [PATCH] Add loadable fields handling on system.text.json serializer --- back/src/Kyoo.Core/CoreModule.cs | 5 +++- .../Helper/Serializers/WithKindResolver.cs | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/back/src/Kyoo.Core/CoreModule.cs b/back/src/Kyoo.Core/CoreModule.cs index 73b97dd9..6a0c36f3 100644 --- a/back/src/Kyoo.Core/CoreModule.cs +++ b/back/src/Kyoo.Core/CoreModule.cs @@ -95,8 +95,11 @@ namespace Kyoo.Core }) .AddJsonOptions(x => { + x.JsonSerializerOptions.TypeInfoResolver = new WithKindResolver() + { + Modifiers = { WithKindResolver.HandleLoadableFields } + }; x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); - x.JsonSerializerOptions.TypeInfoResolver = new WithKindResolver(); x.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }) .AddDataAnnotations() diff --git a/back/src/Kyoo.Core/Views/Helper/Serializers/WithKindResolver.cs b/back/src/Kyoo.Core/Views/Helper/Serializers/WithKindResolver.cs index 7c120aae..cfc65c26 100644 --- a/back/src/Kyoo.Core/Views/Helper/Serializers/WithKindResolver.cs +++ b/back/src/Kyoo.Core/Views/Helper/Serializers/WithKindResolver.cs @@ -18,10 +18,13 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Text.Json; using System.Text.Json.Serialization.Metadata; using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; +using Microsoft.AspNetCore.Http; using static System.Text.Json.JsonNamingPolicy; namespace Kyoo.Core.Api; @@ -53,4 +56,24 @@ public class WithKindResolver : DefaultJsonTypeInfoResolver return jsonTypeInfo; } + + private static readonly IHttpContextAccessor _accessor = new HttpContextAccessor(); + + public static void HandleLoadableFields(JsonTypeInfo info) + { + foreach (JsonPropertyInfo prop in info.Properties) + { + object[] attributes = + prop.AttributeProvider?.GetCustomAttributes(typeof(LoadableRelationAttribute), true) + ?? Array.Empty(); + if (attributes.FirstOrDefault() is not LoadableRelationAttribute relation) + continue; + prop.ShouldSerialize = (_, _) => + { + if (_accessor?.HttpContext?.Items["fields"] is not ICollection fields) + return false; + return fields.Contains(prop.Name, StringComparer.InvariantCultureIgnoreCase); + }; + } + } }