diff --git a/back/Dockerfile.dev b/back/Dockerfile.dev index ac2a62e9..19be75df 100644 --- a/back/Dockerfile.dev +++ b/back/Dockerfile.dev @@ -20,4 +20,4 @@ EXPOSE 5000 ENV DOTNET_USE_POLLING_FILE_WATCHER 1 # HEALTHCHECK --interval=5s CMD curl --fail http://localhost:5000/health || exit HEALTHCHECK CMD true -ENTRYPOINT ["dotnet", "watch", "run", "--no-restore", "--project", "/app/src/Kyoo.Host"] +ENTRYPOINT ["dotnet", "watch", "--non-interactive", "run", "--no-restore", "--project", "/app/src/Kyoo.Host"] diff --git a/back/src/Kyoo.Core/Views/Helper/Serializers/WithKindResolver.cs b/back/src/Kyoo.Abstractions/Utility/JsonKindResolver.cs similarity index 75% rename from back/src/Kyoo.Core/Views/Helper/Serializers/WithKindResolver.cs rename to back/src/Kyoo.Abstractions/Utility/JsonKindResolver.cs index 0cf61131..45cdfdaa 100644 --- a/back/src/Kyoo.Core/Views/Helper/Serializers/WithKindResolver.cs +++ b/back/src/Kyoo.Abstractions/Utility/JsonKindResolver.cs @@ -28,9 +28,9 @@ using Kyoo.Abstractions.Models.Attributes; using Microsoft.AspNetCore.Http; using static System.Text.Json.JsonNamingPolicy; -namespace Kyoo.Core.Api; +namespace Kyoo.Utils; -public class WithKindResolver : DefaultJsonTypeInfoResolver +public class JsonKindResolver : DefaultJsonTypeInfoResolver { public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options) { @@ -76,24 +76,4 @@ 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); - }; - } - } } diff --git a/back/src/Kyoo.Abstractions/Utility/Utility.cs b/back/src/Kyoo.Abstractions/Utility/Utility.cs index a964d1e4..dcd3b35c 100644 --- a/back/src/Kyoo.Abstractions/Utility/Utility.cs +++ b/back/src/Kyoo.Abstractions/Utility/Utility.cs @@ -23,6 +23,8 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Text.RegularExpressions; namespace Kyoo.Utils; @@ -32,6 +34,15 @@ namespace Kyoo.Utils; /// public static class Utility { + public static readonly JsonSerializerOptions JsonOptions = + new() + { + TypeInfoResolver = new JsonKindResolver(), + Converters = { new JsonStringEnumConverter() }, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + /// /// Convert a string to snake case. Stollen from /// https://github.com/efcore/EFCore.NamingConventions/blob/main/EFCore.NamingConventions/Internal/SnakeCaseNameRewriter.cs diff --git a/back/src/Kyoo.Core/CoreModule.cs b/back/src/Kyoo.Core/CoreModule.cs index e7b27081..8d683b80 100644 --- a/back/src/Kyoo.Core/CoreModule.cs +++ b/back/src/Kyoo.Core/CoreModule.cs @@ -28,6 +28,7 @@ using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models.Utils; using Kyoo.Core.Api; using Kyoo.Core.Controllers; +using Kyoo.Utils; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; @@ -95,9 +96,9 @@ public class CoreModule : IPlugin }) .AddJsonOptions(x => { - x.JsonSerializerOptions.TypeInfoResolver = new WithKindResolver() + x.JsonSerializerOptions.TypeInfoResolver = new JsonKindResolver() { - Modifiers = { WithKindResolver.HandleLoadableFields } + Modifiers = { IncludeBinder.HandleLoadableFields } }; x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); x.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; diff --git a/back/src/Kyoo.Core/Views/Helper/IncludeBinder.cs b/back/src/Kyoo.Core/Views/Helper/IncludeBinder.cs index 3ddab91b..fd783946 100644 --- a/back/src/Kyoo.Core/Views/Helper/IncludeBinder.cs +++ b/back/src/Kyoo.Core/Views/Helper/IncludeBinder.cs @@ -17,9 +17,14 @@ // along with Kyoo. If not, see . using System; +using System.Collections.Generic; +using System.Linq; using System.Reflection; +using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; +using Kyoo.Abstractions.Models.Attributes; using Kyoo.Abstractions.Models.Utils; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; @@ -49,6 +54,26 @@ public class IncludeBinder : IModelBinder } } + 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) + ?? []; + 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); + }; + } + } + public class Provider : IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) diff --git a/back/src/Kyoo.RabbitMq/Message.cs b/back/src/Kyoo.RabbitMq/Message.cs index 67e12760..72fa2f37 100644 --- a/back/src/Kyoo.RabbitMq/Message.cs +++ b/back/src/Kyoo.RabbitMq/Message.cs @@ -18,6 +18,7 @@ using System.Text; using System.Text.Json; +using Kyoo.Utils; namespace Kyoo.RabbitMq; @@ -34,6 +35,6 @@ public class Message public byte[] AsBytes() { - return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(this)); + return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(this, Utility.JsonOptions)); } }