diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index 71ef9a69a2..00688074f0 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
@@ -4,6 +4,7 @@ using Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy;
using Jellyfin.Api.Auth.RequiresElevationPolicy;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Controllers;
+using Jellyfin.Server.Formatters;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
@@ -66,6 +67,8 @@ namespace Jellyfin.Server.Extensions
return serviceCollection.AddMvc(opts =>
{
opts.UseGeneralRoutePrefix(baseUrl);
+ opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter());
+ opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter());
})
// Clear app parts to avoid other assemblies being picked up
diff --git a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs
new file mode 100644
index 0000000000..e6ad6dfb13
--- /dev/null
+++ b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs
@@ -0,0 +1,21 @@
+using Jellyfin.Server.Models;
+using Microsoft.AspNetCore.Mvc.Formatters;
+using Microsoft.Net.Http.Headers;
+
+namespace Jellyfin.Server.Formatters
+{
+ ///
+ /// Camel Case Json Profile Formatter.
+ ///
+ public class CamelCaseJsonProfileFormatter : SystemTextJsonOutputFormatter
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public CamelCaseJsonProfileFormatter() : base(JsonOptions.CamelCase)
+ {
+ SupportedMediaTypes.Clear();
+ SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json;profile=\"CamelCase\""));
+ }
+ }
+}
diff --git a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs
new file mode 100644
index 0000000000..675f4c79ee
--- /dev/null
+++ b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs
@@ -0,0 +1,23 @@
+using Jellyfin.Server.Models;
+using Microsoft.AspNetCore.Mvc.Formatters;
+using Microsoft.Net.Http.Headers;
+
+namespace Jellyfin.Server.Formatters
+{
+ ///
+ /// Pascal Case Json Profile Formatter.
+ ///
+ public class PascalCaseJsonProfileFormatter : SystemTextJsonOutputFormatter
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public PascalCaseJsonProfileFormatter() : base(JsonOptions.PascalCase)
+ {
+ SupportedMediaTypes.Clear();
+ // Add application/json for default formatter
+ SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
+ SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json;profile=\"PascalCase\""));
+ }
+ }
+}
diff --git a/Jellyfin.Server/Models/JsonOptions.cs b/Jellyfin.Server/Models/JsonOptions.cs
new file mode 100644
index 0000000000..2f0df3d2c7
--- /dev/null
+++ b/Jellyfin.Server/Models/JsonOptions.cs
@@ -0,0 +1,41 @@
+using System.Text.Json;
+
+namespace Jellyfin.Server.Models
+{
+ ///
+ /// Json Options.
+ ///
+ public static class JsonOptions
+ {
+ ///
+ /// Gets CamelCase json options.
+ ///
+ public static JsonSerializerOptions CamelCase
+ {
+ get
+ {
+ var options = DefaultJsonOptions;
+ options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
+ return options;
+ }
+ }
+
+ ///
+ /// Gets PascalCase json options.
+ ///
+ public static JsonSerializerOptions PascalCase
+ {
+ get
+ {
+ var options = DefaultJsonOptions;
+ options.PropertyNamingPolicy = null;
+ return options;
+ }
+ }
+
+ ///
+ /// Gets base Json Serializer Options.
+ ///
+ private static JsonSerializerOptions DefaultJsonOptions => new JsonSerializerOptions();
+ }
+}