diff --git a/src/Kyoo.Core/CoreModule.cs b/src/Kyoo.Core/CoreModule.cs
index f601ad25..dd5f2e39 100644
--- a/src/Kyoo.Core/CoreModule.cs
+++ b/src/Kyoo.Core/CoreModule.cs
@@ -26,7 +26,6 @@ using Autofac.Extras.AttributeMetadata;
using Kyoo.Abstractions;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models.Utils;
-using Kyoo.Core.Api;
using Kyoo.Core.Controllers;
using Kyoo.Core.Models.Options;
using Kyoo.Core.Tasks;
@@ -35,11 +34,12 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.StaticFiles;
-using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Options;
using Serilog;
using IMetadataProvider = Kyoo.Abstractions.Controllers.IMetadataProvider;
+using JsonOptions = Kyoo.Core.Api.JsonOptions;
namespace Kyoo.Core
{
@@ -67,20 +67,6 @@ namespace Kyoo.Core
{ "logging", null }
};
- ///
- /// The configuration to use.
- ///
- private readonly IConfiguration _configuration;
-
- ///
- /// Create a new core module instance and use the given configuration.
- ///
- /// The configuration to use
- public CoreModule(IConfiguration configuration)
- {
- _configuration = configuration;
- }
-
///
public void Configure(ContainerBuilder builder)
{
@@ -140,17 +126,13 @@ namespace Kyoo.Core
///
public void Configure(IServiceCollection services)
{
- Uri publicUrl = _configuration.GetPublicUrl();
+ services.AddTransient, JsonOptions>();
services.AddMvcCore()
+ .AddNewtonsoftJson()
.AddDataAnnotations()
.AddControllersAsServices()
.AddApiExplorer()
- .AddNewtonsoftJson(x =>
- {
- x.SerializerSettings.ContractResolver = new JsonPropertyIgnorer(publicUrl);
- x.SerializerSettings.Converters.Add(new PeopleRoleConverter());
- })
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressMapClientErrors = true;
diff --git a/src/Kyoo.Core/Views/Helper/ResourceViewAttribute.cs b/src/Kyoo.Core/Views/Helper/ResourceViewAttribute.cs
index 6cc70187..3bb12b3a 100644
--- a/src/Kyoo.Core/Views/Helper/ResourceViewAttribute.cs
+++ b/src/Kyoo.Core/Views/Helper/ResourceViewAttribute.cs
@@ -24,6 +24,7 @@ using System.Threading.Tasks;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models;
using Kyoo.Abstractions.Models.Attributes;
+using Kyoo.Abstractions.Models.Utils;
using Kyoo.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
@@ -64,13 +65,13 @@ namespace Kyoo.Core.Api
type = Utility.GetGenericDefinition(type, typeof(ActionResult<>))?.GetGenericArguments()[0] ?? type;
type = Utility.GetGenericDefinition(type, typeof(Page<>))?.GetGenericArguments()[0] ?? type;
+ context.HttpContext.Items["ResourceType"] = type.Name;
+
PropertyInfo[] properties = type.GetProperties()
.Where(x => x.GetCustomAttribute() != null)
.ToArray();
if (fields.Count == 1 && fields.Contains("all"))
- {
fields = properties.Select(x => x.Name).ToList();
- }
else
{
fields = fields
@@ -82,10 +83,9 @@ namespace Kyoo.Core.Api
?.Name;
if (property != null)
return property;
- context.Result = new BadRequestObjectResult(new
- {
- Error = $"{x} does not exist on {type.Name}."
- });
+ context.Result = new BadRequestObjectResult(
+ new RequestError($"{x} does not exist on {type.Name}.")
+ );
return null;
})
.ToList();
@@ -110,7 +110,7 @@ namespace Kyoo.Core.Api
if (result.DeclaredType == null)
return;
- ILibraryManager library = context.HttpContext.RequestServices.GetService();
+ ILibraryManager library = context.HttpContext.RequestServices.GetRequiredService();
ICollection fields = (ICollection)context.HttpContext.Items["fields"];
Type pageType = Utility.GetGenericDefinition(result.DeclaredType, typeof(Page<>));
@@ -119,13 +119,13 @@ namespace Kyoo.Core.Api
foreach (IResource resource in ((dynamic)result.Value).Items)
{
foreach (string field in fields!)
- await library!.Load(resource, field);
+ await library.Load(resource, field);
}
}
else if (result.DeclaredType.IsAssignableTo(typeof(IResource)))
{
foreach (string field in fields!)
- await library!.Load((IResource)result.Value, field);
+ await library.Load((IResource)result.Value, field);
}
}
}
diff --git a/src/Kyoo.Core/Views/Helper/Serializers/JsonOptions.cs b/src/Kyoo.Core/Views/Helper/Serializers/JsonOptions.cs
new file mode 100644
index 00000000..c272e942
--- /dev/null
+++ b/src/Kyoo.Core/Views/Helper/Serializers/JsonOptions.cs
@@ -0,0 +1,54 @@
+// 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);
+ options.SerializerSettings.Converters.Add(new PeopleRoleConverter());
+ }
+ }
+}
diff --git a/src/Kyoo.Core/Views/Helper/Serializers/JsonPropertyIgnorer.cs b/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
similarity index 52%
rename from src/Kyoo.Core/Views/Helper/Serializers/JsonPropertyIgnorer.cs
rename to src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
index 40a682a9..0fef35fc 100644
--- a/src/Kyoo.Core/Views/Helper/Serializers/JsonPropertyIgnorer.cs
+++ b/src/Kyoo.Core/Views/Helper/Serializers/JsonSerializerContract.cs
@@ -16,27 +16,39 @@
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see .
-using System;
-using System.Collections;
+using System.Collections.Generic;
using System.Reflection;
using Kyoo.Abstractions.Models;
using Kyoo.Abstractions.Models.Attributes;
-using Kyoo.Utils;
+using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Kyoo.Core.Api
{
- public class JsonPropertyIgnorer : CamelCasePropertyNamesContractResolver
+ ///
+ /// A custom json serializer that respects and
+ /// . It also handle via the
+ /// fields query parameter and items.
+ ///
+ public class JsonSerializerContract : CamelCasePropertyNamesContractResolver
{
- private readonly Uri _host;
- private int _depth = -1;
+ ///
+ /// The http context accessor used to retrieve the fields query parameter as well as the type of
+ /// resource currently serializing.
+ ///
+ private readonly IHttpContextAccessor _httpContextAccessor;
- public JsonPropertyIgnorer(Uri host)
+ ///
+ /// Create a new .
+ ///
+ /// The http context accessor to use.
+ public JsonSerializerContract(IHttpContextAccessor httpContextAccessor)
{
- _host = host;
+ _httpContextAccessor = httpContextAccessor;
}
+ ///
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
@@ -44,19 +56,14 @@ namespace Kyoo.Core.Api
LoadableRelationAttribute relation = member.GetCustomAttribute();
if (relation != null)
{
- if (relation.RelationID == null)
- property.ShouldSerialize = x => _depth == 0 && member.GetValue(x) != null;
- else
+ property.ShouldSerialize = _ =>
{
- property.ShouldSerialize = x =>
- {
- if (_depth != 0)
- return false;
- if (member.GetValue(x) != null)
- return true;
- return x.GetType().GetProperty(relation.RelationID)?.GetValue(x) != null;
- };
- }
+ string resType = (string)_httpContextAccessor.HttpContext!.Items["ResourceType"];
+ if (member.DeclaringType!.Name != resType)
+ return false;
+ ICollection fields = (ICollection)_httpContextAccessor.HttpContext!.Items["fields"];
+ return fields!.Contains(member.Name);
+ };
}
if (member.GetCustomAttribute() != null)
@@ -66,24 +73,10 @@ namespace Kyoo.Core.Api
// TODO use http context to disable serialize as.
// TODO check https://stackoverflow.com/questions/53288633/net-core-api-custom-json-resolver-based-on-request-values
- SerializeAsAttribute serializeAs = member.GetCustomAttribute();
- if (serializeAs != null)
- property.ValueProvider = new SerializeAsProvider(serializeAs.Format, _host);
+ // SerializeAsAttribute serializeAs = member.GetCustomAttribute();
+ // if (serializeAs != null)
+ // property.ValueProvider = new SerializeAsProvider(serializeAs.Format, _host);
return property;
}
-
- protected override JsonContract CreateContract(Type objectType)
- {
- JsonContract contract = base.CreateContract(objectType);
- if (Utility.GetGenericDefinition(objectType, typeof(Page<>)) == null
- && !objectType.IsAssignableTo(typeof(IEnumerable))
- && objectType.Name != "AnnotatedProblemDetails")
- {
- contract.OnSerializingCallbacks.Add((_, _) => _depth++);
- contract.OnSerializedCallbacks.Add((_, _) => _depth--);
- }
-
- return contract;
- }
}
}
diff --git a/tests/Kyoo.Tests/Kyoo.Tests.csproj b/tests/Kyoo.Tests/Kyoo.Tests.csproj
index 330c41f7..c02609c5 100644
--- a/tests/Kyoo.Tests/Kyoo.Tests.csproj
+++ b/tests/Kyoo.Tests/Kyoo.Tests.csproj
@@ -1,12 +1,8 @@
-
net5.0
default
false
-
- Zoe Roux
- SDG
@@ -37,5 +33,4 @@
-