diff --git a/back/src/Kyoo.Core/CoreModule.cs b/back/src/Kyoo.Core/CoreModule.cs index d3341e31..13ed6b54 100644 --- a/back/src/Kyoo.Core/CoreModule.cs +++ b/back/src/Kyoo.Core/CoreModule.cs @@ -19,6 +19,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; using AspNetCore.Proxy; using Autofac; using Kyoo.Abstractions; @@ -30,10 +32,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using JsonOptions = Kyoo.Core.Api.JsonOptions; namespace Kyoo.Core { @@ -86,7 +84,6 @@ namespace Kyoo.Core public void Configure(IServiceCollection services) { services.AddHttpContextAccessor(); - services.AddTransient, JsonOptions>(); services .AddMvcCore(options => @@ -96,10 +93,11 @@ namespace Kyoo.Core options.ModelBinderProviders.Insert(0, new IncludeBinder.Provider()); options.ModelBinderProviders.Insert(0, new FilterBinder.Provider()); }) - .AddNewtonsoftJson(x => + .AddJsonOptions(x => { - x.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; - x.SerializerSettings.Converters.Add(new StringEnumConverter()); + x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); + x.JsonSerializerOptions.TypeInfoResolver = new PolymorphicTypeResolver(); + x.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }) .AddDataAnnotations() .AddControllersAsServices() diff --git a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonOptions.cs b/back/src/Kyoo.Core/Views/Helper/Serializers/JsonOptions.cs deleted file mode 100644 index f44796d5..00000000 --- a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonOptions.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Kyoo - A portable and vast media library solution. -// Copyright (c) Kyoo. -// -// See AUTHORS.md and LICENSE file in the project root for full license information. -// -// Kyoo is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// any later version. -// -// Kyoo is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Kyoo. If not, see . - -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Options; - -namespace Kyoo.Core.Api -{ - /// - /// The custom options of newtonsoft json. This simply add the and set - /// the . It is on a separate class to use dependency injection. - /// - public class JsonOptions : IConfigureOptions - { - /// - /// The http context accessor given to the . - /// - private readonly IHttpContextAccessor _httpContextAccessor; - - /// - /// Create a new . - /// - /// - /// The http context accessor given to the . - /// - public JsonOptions(IHttpContextAccessor httpContextAccessor) - { - _httpContextAccessor = httpContextAccessor; - } - - /// - public void Configure(MvcNewtonsoftJsonOptions options) - { - options.SerializerSettings.ContractResolver = new JsonSerializerContract( - _httpContextAccessor - ); - } - } -} diff --git a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs b/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs index cfba3390..b3f5b0c7 100644 --- a/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs +++ b/back/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs @@ -1,117 +1,69 @@ -// Kyoo - A portable and vast media library solution. -// Copyright (c) Kyoo. +// // Kyoo - A portable and vast media library solution. +// // Copyright (c) Kyoo. +// // +// // See AUTHORS.md and LICENSE file in the project root for full license information. +// // +// // Kyoo is free software: you can redistribute it and/or modify +// // it under the terms of the GNU General Public License as published by +// // the Free Software Foundation, either version 3 of the License, or +// // any later version. +// // +// // Kyoo is distributed in the hope that it will be useful, +// // but WITHOUT ANY WARRANTY; without even the implied warranty of +// // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// // GNU General Public License for more details. +// // +// // You should have received a copy of the GNU General Public License +// // along with Kyoo. If not, see . // -// See AUTHORS.md and LICENSE file in the project root for full license information. +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using System.Net.Http.Formatting; +// using System.Reflection; +// using Kyoo.Abstractions.Models; +// using Kyoo.Abstractions.Models.Attributes; +// using Microsoft.AspNetCore.Http; +// using static System.Text.Json.JsonNamingPolicy; // -// Kyoo is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// any later version. +// namespace Kyoo.Core.Api +// { +// /// +// /// A custom json serializer that respects and +// /// . It also handle via the +// /// fields query parameter and items. +// /// +// public class JsonSerializerContract(IHttpContextAccessor? httpContextAccessor, MediaTypeFormatter formatter) +// : JsonContractResolver(formatter) +// { +// /// +// protected override JsonProperty CreateProperty( +// MemberInfo member, +// MemberSerialization memberSerialization +// ) +// { +// JsonProperty property = base.CreateProperty(member, memberSerialization); // -// Kyoo is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Kyoo. If not, see . - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Kyoo.Abstractions.Models; -using Kyoo.Abstractions.Models.Attributes; -using Microsoft.AspNetCore.Http; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; -using static System.Text.Json.JsonNamingPolicy; - -namespace Kyoo.Core.Api -{ - /// - /// A custom json serializer that respects and - /// . It also handle via the - /// fields query parameter and items. - /// - public class JsonSerializerContract : CamelCasePropertyNamesContractResolver - { - /// - /// The http context accessor used to retrieve the fields query parameter as well as the type of - /// resource currently serializing. - /// - private readonly IHttpContextAccessor _httpContextAccessor; - - /// - /// Create a new . - /// - /// The http context accessor to use. - public JsonSerializerContract(IHttpContextAccessor httpContextAccessor) - { - _httpContextAccessor = httpContextAccessor; - } - - /// - protected override JsonProperty CreateProperty( - MemberInfo member, - MemberSerialization memberSerialization - ) - { - JsonProperty property = base.CreateProperty(member, memberSerialization); - - LoadableRelationAttribute? relation = - member.GetCustomAttribute(); - if (relation != null) - { - property.ShouldSerialize = _ => - { - if ( - _httpContextAccessor.HttpContext!.Items["fields"] - is not ICollection fields - ) - return false; - return fields.Contains(member.Name); - }; - } - return property; - } - - protected override IList CreateProperties( - Type type, - MemberSerialization memberSerialization - ) - { - IList properties = base.CreateProperties(type, memberSerialization); - - if ( - properties.All(x => x.PropertyName != "kind") - && type.IsAssignableTo(typeof(IResource)) - ) - { - properties.Add( - new JsonProperty() - { - DeclaringType = type, - PropertyName = "kind", - UnderlyingName = "kind", - PropertyType = typeof(string), - ValueProvider = new FixedValueProvider(CamelCase.ConvertName(type.Name)), - Readable = true, - Writable = false, - TypeNameHandling = TypeNameHandling.None, - } - ); - } - - return properties; - } - - public class FixedValueProvider(object value) : IValueProvider - { - public object GetValue(object target) => value; - - public void SetValue(object target, object? value) => - throw new NotImplementedException(); - } - } -} +// LoadableRelationAttribute? relation = +// member.GetCustomAttribute(); +// if (relation != null) +// { +// if (httpContextAccessor != null) +// { +// property.ShouldSerialize = _ => +// { +// if ( +// httpContextAccessor.HttpContext!.Items["fields"] +// is not ICollection fields +// ) +// return false; +// return fields.Contains(member.Name); +// }; +// } +// else +// property.ShouldSerialize = _ => true; +// } +// return property; +// } +// } +// } diff --git a/back/src/Kyoo.Core/Views/Helper/Serializers/TypeInfoResolver.cs b/back/src/Kyoo.Core/Views/Helper/Serializers/TypeInfoResolver.cs new file mode 100644 index 00000000..73919295 --- /dev/null +++ b/back/src/Kyoo.Core/Views/Helper/Serializers/TypeInfoResolver.cs @@ -0,0 +1,64 @@ +// Kyoo - A portable and vast media library solution. +// Copyright (c) Kyoo. +// +// See AUTHORS.md and LICENSE file in the project root for full license information. +// +// Kyoo is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// Kyoo is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Kyoo. If not, see . + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Metadata; +using Kyoo.Abstractions.Models; +using static System.Text.Json.JsonNamingPolicy; + +namespace Kyoo.Core.Api; + +public class PolymorphicTypeResolver : DefaultJsonTypeInfoResolver +{ + private static readonly IList _types = AppDomain + .CurrentDomain.GetAssemblies() + .SelectMany(s => s.GetTypes()) + .Where(p => p.IsAssignableTo(typeof(IResource)) && p.IsClass) + .Select(x => new JsonDerivedType(x, CamelCase.ConvertName(x.Name))) + .ToList(); + + public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options) + { + JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options); + + if ( + jsonTypeInfo.Type.IsAssignableTo(typeof(IResource)) + && jsonTypeInfo.Properties.All(x => x.Name != "kind") + ) + { + jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions + { + TypeDiscriminatorPropertyName = "kind", + IgnoreUnrecognizedTypeDiscriminators = true, + UnknownDerivedTypeHandling = + JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor, + DerivedTypes = { }, + }; + Console.WriteLine(string.Join(",", _types.Select(x => x.DerivedType.Name))); + foreach (JsonDerivedType derived in _types) + jsonTypeInfo.PolymorphismOptions.DerivedTypes.Add(derived); + } + + return jsonTypeInfo; + } +}