Use new json serializer in rabbitmq contetxs

This commit is contained in:
Zoe Roux 2024-03-23 15:09:08 +01:00
parent 851baa030c
commit 7905edaf24
No known key found for this signature in database
6 changed files with 44 additions and 26 deletions

View File

@ -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"]

View File

@ -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<object>();
if (attributes.FirstOrDefault() is not LoadableRelationAttribute relation)
continue;
prop.ShouldSerialize = (_, _) =>
{
if (_accessor?.HttpContext?.Items["fields"] is not ICollection<string> fields)
return false;
return fields.Contains(prop.Name, StringComparer.InvariantCultureIgnoreCase);
};
}
}
}

View File

@ -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;
/// </summary>
public static class Utility
{
public static readonly JsonSerializerOptions JsonOptions =
new()
{
TypeInfoResolver = new JsonKindResolver(),
Converters = { new JsonStringEnumConverter() },
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
/// <summary>
/// Convert a string to snake case. Stollen from
/// https://github.com/efcore/EFCore.NamingConventions/blob/main/EFCore.NamingConventions/Internal/SnakeCaseNameRewriter.cs

View File

@ -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;

View File

@ -17,9 +17,14 @@
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
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<string> fields)
return false;
return fields.Contains(prop.Name, StringComparer.InvariantCultureIgnoreCase);
};
}
}
public class Provider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)

View File

@ -18,6 +18,7 @@
using System.Text;
using System.Text.Json;
using Kyoo.Utils;
namespace Kyoo.RabbitMq;
@ -34,6 +35,6 @@ public class Message<T>
public byte[] AsBytes()
{
return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(this));
return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(this, Utility.JsonOptions));
}
}