From ad67081840ec61085673634795d0b6363f649dbf Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 19 Apr 2020 18:04:36 -0600 Subject: add camelCase formatter --- .../Formatters/CamelCaseJsonProfileFormatter.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs (limited to 'Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs') diff --git a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs new file mode 100644 index 000000000..433a3197d --- /dev/null +++ b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs @@ -0,0 +1,21 @@ +using System.Text.Json; +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(new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }) + { + SupportedMediaTypes.Clear(); + SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json;profile=\"CamelCase\"")); + } + } +} -- cgit v1.2.3 From fe632146dcba69edeec56b850736227ff5f4c5b3 Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 21 Apr 2020 08:17:13 -0600 Subject: Move Json Options to static class for easier access. --- .../Formatters/CamelCaseJsonProfileFormatter.cs | 4 +-- .../Formatters/PascalCaseJsonProfileFormatter.cs | 4 +-- Jellyfin.Server/Models/JsonOptions.cs | 41 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 Jellyfin.Server/Models/JsonOptions.cs (limited to 'Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs') diff --git a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs index 433a3197d..e6ad6dfb1 100644 --- a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs @@ -1,4 +1,4 @@ -using System.Text.Json; +using Jellyfin.Server.Models; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Net.Http.Headers; @@ -12,7 +12,7 @@ namespace Jellyfin.Server.Formatters /// /// Initializes a new instance of the class. /// - public CamelCaseJsonProfileFormatter() : base(new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }) + 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 index 2ed006a33..675f4c79e 100644 --- a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs @@ -1,4 +1,4 @@ -using System.Text.Json; +using Jellyfin.Server.Models; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Net.Http.Headers; @@ -12,7 +12,7 @@ namespace Jellyfin.Server.Formatters /// /// Initializes a new instance of the class. /// - public PascalCaseJsonProfileFormatter() : base(new JsonSerializerOptions { PropertyNamingPolicy = null }) + public PascalCaseJsonProfileFormatter() : base(JsonOptions.PascalCase) { SupportedMediaTypes.Clear(); // Add application/json for default formatter diff --git a/Jellyfin.Server/Models/JsonOptions.cs b/Jellyfin.Server/Models/JsonOptions.cs new file mode 100644 index 000000000..fa503bc9a --- /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 + { + /// + /// Base Json Serializer Options. + /// + private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions(); + + /// + /// Gets CamelCase json options. + /// + public static JsonSerializerOptions CamelCase + { + get + { + var options = _jsonOptions; + options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + return options; + } + } + + /// + /// Gets PascalCase json options. + /// + public static JsonSerializerOptions PascalCase + { + get + { + var options = _jsonOptions; + options.PropertyNamingPolicy = null; + return options; + } + } + } +} -- cgit v1.2.3 From 4fe0beec162d4554f1d6cc3c658b672eafbfa307 Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 21 May 2020 08:44:15 -0600 Subject: Fix Json Enum conversion, map all JsonDefaults properties to API --- .../Extensions/ApiServiceCollectionExtensions.cs | 22 ++++++++---- .../Formatters/CamelCaseJsonProfileFormatter.cs | 4 +-- .../Formatters/PascalCaseJsonProfileFormatter.cs | 4 +-- Jellyfin.Server/Models/JsonOptions.cs | 41 ---------------------- MediaBrowser.Common/Json/JsonDefaults.cs | 34 +++++++++++++++++- 5 files changed, 53 insertions(+), 52 deletions(-) delete mode 100644 Jellyfin.Server/Models/JsonOptions.cs (limited to 'Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs') diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index 344ef6a5f..b9f55e200 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Reflection; -using System.Text.Json.Serialization; using Jellyfin.Api; using Jellyfin.Api.Auth; using Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy; @@ -11,6 +8,7 @@ using Jellyfin.Api.Auth.RequiresElevationPolicy; using Jellyfin.Api.Constants; using Jellyfin.Api.Controllers; using Jellyfin.Server.Formatters; +using MediaBrowser.Common.Json; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; @@ -83,8 +81,20 @@ namespace Jellyfin.Server.Extensions .AddApplicationPart(typeof(StartupController).Assembly) .AddJsonOptions(options => { - // Setting the naming policy to null leaves the property names as-is when serializing objects to JSON. - options.JsonSerializerOptions.PropertyNamingPolicy = null; + // Update all properties that are set in JsonDefaults + var jsonOptions = JsonDefaults.PascalCase; + + // From JsonDefaults + options.JsonSerializerOptions.ReadCommentHandling = jsonOptions.ReadCommentHandling; + options.JsonSerializerOptions.WriteIndented = jsonOptions.WriteIndented; + options.JsonSerializerOptions.Converters.Clear(); + foreach (var converter in jsonOptions.Converters) + { + options.JsonSerializerOptions.Converters.Add(converter); + } + + // From JsonDefaults.PascalCase + options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy; }) .AddControllersAsServices(); } @@ -98,7 +108,7 @@ namespace Jellyfin.Server.Extensions { return serviceCollection.AddSwaggerGen(c => { - c.SwaggerDoc("api-docs", new OpenApiInfo { Title = "Jellyfin API" }); + c.SwaggerDoc("api-docs", new OpenApiInfo { Title = "Jellyfin API", Version = "v1" }); // Add all xml doc files to swagger generator. var xmlFiles = Directory.GetFiles( diff --git a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs index e6ad6dfb1..989c8ecea 100644 --- a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs @@ -1,4 +1,4 @@ -using Jellyfin.Server.Models; +using MediaBrowser.Common.Json; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Net.Http.Headers; @@ -12,7 +12,7 @@ namespace Jellyfin.Server.Formatters /// /// Initializes a new instance of the class. /// - public CamelCaseJsonProfileFormatter() : base(JsonOptions.CamelCase) + public CamelCaseJsonProfileFormatter() : base(JsonDefaults.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 index 675f4c79e..69963b3fb 100644 --- a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs @@ -1,4 +1,4 @@ -using Jellyfin.Server.Models; +using MediaBrowser.Common.Json; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Net.Http.Headers; @@ -12,7 +12,7 @@ namespace Jellyfin.Server.Formatters /// /// Initializes a new instance of the class. /// - public PascalCaseJsonProfileFormatter() : base(JsonOptions.PascalCase) + public PascalCaseJsonProfileFormatter() : base(JsonDefaults.PascalCase) { SupportedMediaTypes.Clear(); // Add application/json for default formatter diff --git a/Jellyfin.Server/Models/JsonOptions.cs b/Jellyfin.Server/Models/JsonOptions.cs deleted file mode 100644 index 2f0df3d2c..000000000 --- a/Jellyfin.Server/Models/JsonOptions.cs +++ /dev/null @@ -1,41 +0,0 @@ -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(); - } -} diff --git a/MediaBrowser.Common/Json/JsonDefaults.cs b/MediaBrowser.Common/Json/JsonDefaults.cs index 4a6ee0a79..326f04eea 100644 --- a/MediaBrowser.Common/Json/JsonDefaults.cs +++ b/MediaBrowser.Common/Json/JsonDefaults.cs @@ -12,10 +12,16 @@ namespace MediaBrowser.Common.Json /// /// Gets the default options. /// + /// + /// When changing these options, update + /// Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs + /// -> AddJellyfinApi + /// -> AddJsonOptions + /// /// The default options. public static JsonSerializerOptions GetOptions() { - var options = new JsonSerializerOptions() + var options = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Disallow, WriteIndented = false @@ -26,5 +32,31 @@ namespace MediaBrowser.Common.Json return options; } + + /// + /// Gets CamelCase json options. + /// + public static JsonSerializerOptions CamelCase + { + get + { + var options = GetOptions(); + options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + return options; + } + } + + /// + /// Gets PascalCase json options. + /// + public static JsonSerializerOptions PascalCase + { + get + { + var options = GetOptions(); + options.PropertyNamingPolicy = null; + return options; + } + } } } -- cgit v1.2.3 From ec3e15db5789b6218482beb488433f41f9a0d8ba Mon Sep 17 00:00:00 2001 From: crobibero Date: Sat, 13 Jun 2020 13:11:41 -0600 Subject: Fix merge and build --- Jellyfin.Api/BaseJellyfinApiController.cs | 4 -- Jellyfin.Api/Controllers/ActivityLogController.cs | 11 +++- .../ConfigurationDtos/MediaEncoderPathDto.cs | 6 +- .../Extensions/ApiServiceCollectionExtensions.cs | 2 +- .../Formatters/CamelCaseJsonProfileFormatter.cs | 2 +- .../Formatters/PascalCaseJsonProfileFormatter.cs | 2 +- MediaBrowser.Api/MediaBrowser.Api.csproj | 4 -- MediaBrowser.Api/System/ActivityLogService.cs | 66 ---------------------- .../JsonNonStringKeyDictionaryConverter.cs | 26 +++++---- .../JsonNonStringKeyDictionaryConverterFactory.cs | 5 +- MediaBrowser.Common/Json/JsonDefaults.cs | 30 +++++----- 11 files changed, 46 insertions(+), 112 deletions(-) delete mode 100644 MediaBrowser.Api/System/ActivityLogService.cs (limited to 'Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs') diff --git a/Jellyfin.Api/BaseJellyfinApiController.cs b/Jellyfin.Api/BaseJellyfinApiController.cs index 615f330a4..a34f9eb62 100644 --- a/Jellyfin.Api/BaseJellyfinApiController.cs +++ b/Jellyfin.Api/BaseJellyfinApiController.cs @@ -1,8 +1,4 @@ -<<<<<<< HEAD -using System; -======= using System.Net.Mime; ->>>>>>> origin/master using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api diff --git a/Jellyfin.Api/Controllers/ActivityLogController.cs b/Jellyfin.Api/Controllers/ActivityLogController.cs index 8d37a8373..895d9f719 100644 --- a/Jellyfin.Api/Controllers/ActivityLogController.cs +++ b/Jellyfin.Api/Controllers/ActivityLogController.cs @@ -1,6 +1,10 @@ +#nullable enable +#pragma warning disable CA1801 + using System; -using System.Globalization; +using System.Linq; using Jellyfin.Api.Constants; +using Jellyfin.Data.Entities; using MediaBrowser.Model.Activity; using MediaBrowser.Model.Querying; using Microsoft.AspNetCore.Authorization; @@ -44,7 +48,10 @@ namespace Jellyfin.Api.Controllers [FromQuery] DateTime? minDate, bool? hasUserId) { - return _activityManager.GetActivityLogEntries(minDate, hasUserId, startIndex, limit); + var filterFunc = new Func, IQueryable>( + entries => entries.Where(entry => entry.DateCreated >= minDate)); + + return _activityManager.GetPagedResult(filterFunc, startIndex, limit); } } } diff --git a/Jellyfin.Api/Models/ConfigurationDtos/MediaEncoderPathDto.cs b/Jellyfin.Api/Models/ConfigurationDtos/MediaEncoderPathDto.cs index b05e0cdf5..3706a11e3 100644 --- a/Jellyfin.Api/Models/ConfigurationDtos/MediaEncoderPathDto.cs +++ b/Jellyfin.Api/Models/ConfigurationDtos/MediaEncoderPathDto.cs @@ -1,3 +1,5 @@ +#nullable enable + namespace Jellyfin.Api.Models.ConfigurationDtos { /// @@ -8,11 +10,11 @@ namespace Jellyfin.Api.Models.ConfigurationDtos /// /// Gets or sets media encoder path. /// - public string Path { get; set; } + public string Path { get; set; } = null!; /// /// Gets or sets media encoder path type. /// - public string PathType { get; set; } + public string PathType { get; set; } = null!; } } diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index 86d547af0..9cdaa0eb1 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -93,7 +93,7 @@ namespace Jellyfin.Server.Extensions .AddJsonOptions(options => { // Update all properties that are set in JsonDefaults - var jsonOptions = JsonDefaults.PascalCase; + var jsonOptions = JsonDefaults.GetPascalCaseOptions(); // From JsonDefaults options.JsonSerializerOptions.ReadCommentHandling = jsonOptions.ReadCommentHandling; diff --git a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs index 989c8ecea..9b347ae2c 100644 --- a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs @@ -12,7 +12,7 @@ namespace Jellyfin.Server.Formatters /// /// Initializes a new instance of the class. /// - public CamelCaseJsonProfileFormatter() : base(JsonDefaults.CamelCase) + public CamelCaseJsonProfileFormatter() : base(JsonDefaults.GetCamelCaseOptions()) { SupportedMediaTypes.Clear(); SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json;profile=\"CamelCase\"")); diff --git a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs index 69963b3fb..0024708ba 100644 --- a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs @@ -12,7 +12,7 @@ namespace Jellyfin.Server.Formatters /// /// Initializes a new instance of the class. /// - public PascalCaseJsonProfileFormatter() : base(JsonDefaults.PascalCase) + public PascalCaseJsonProfileFormatter() : base(JsonDefaults.GetPascalCaseOptions()) { SupportedMediaTypes.Clear(); // Add application/json for default formatter diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 0b0c5cc9f..d703bdb05 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -14,10 +14,6 @@ - - - - netstandard2.1 false diff --git a/MediaBrowser.Api/System/ActivityLogService.cs b/MediaBrowser.Api/System/ActivityLogService.cs deleted file mode 100644 index a6bacad4f..000000000 --- a/MediaBrowser.Api/System/ActivityLogService.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Globalization; -using System.Linq; -using Jellyfin.Data.Entities; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Net; -using MediaBrowser.Model.Activity; -using MediaBrowser.Model.Querying; -using MediaBrowser.Model.Services; -using Microsoft.Extensions.Logging; - -namespace MediaBrowser.Api.System -{ - [Route("/System/ActivityLog/Entries", "GET", Summary = "Gets activity log entries")] - public class GetActivityLogs : IReturn> - { - /// - /// Skips over a given number of items within the results. Use for paging. - /// - /// The start index. - [ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] - public int? StartIndex { get; set; } - - /// - /// The maximum number of items to return - /// - /// The limit. - [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] - public int? Limit { get; set; } - - [ApiMember(Name = "MinDate", Description = "Optional. The minimum date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] - public string MinDate { get; set; } - - public bool? HasUserId { get; set; } - } - - [Authenticated(Roles = "Admin")] - public class ActivityLogService : BaseApiService - { - private readonly IActivityManager _activityManager; - - public ActivityLogService( - ILogger logger, - IServerConfigurationManager serverConfigurationManager, - IHttpResultFactory httpResultFactory, - IActivityManager activityManager) - : base(logger, serverConfigurationManager, httpResultFactory) - { - _activityManager = activityManager; - } - - public object Get(GetActivityLogs request) - { - DateTime? minDate = string.IsNullOrWhiteSpace(request.MinDate) ? - (DateTime?)null : - DateTime.Parse(request.MinDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime(); - - var filterFunc = new Func, IQueryable>( - entries => entries.Where(entry => entry.DateCreated >= minDate)); - - var result = _activityManager.GetPagedResult(filterFunc, request.StartIndex, request.Limit); - - return ToOptimizedResult(result); - } - } -} diff --git a/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverter.cs b/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverter.cs index 636ef5372..8053461f0 100644 --- a/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverter.cs +++ b/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverter.cs @@ -25,7 +25,7 @@ namespace MediaBrowser.Common.Json.Converters /// The type to convert. /// The json serializer options. /// Typed dictionary. - /// + /// Dictionary key type not supported. public override IDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var convertedType = typeof(Dictionary<,>).MakeGenericType(typeof(string), typeToConvert.GenericTypeArguments[1]); @@ -38,24 +38,24 @@ namespace MediaBrowser.Common.Json.Converters CultureInfo.CurrentCulture); var enumerator = (IEnumerator)convertedType.GetMethod("GetEnumerator")!.Invoke(value, null); var parse = typeof(TKey).GetMethod( - "Parse", - 0, - BindingFlags.Public | BindingFlags.Static, - null, - CallingConventions.Any, - new[] { typeof(string) }, + "Parse", + 0, + BindingFlags.Public | BindingFlags.Static, + null, + CallingConventions.Any, + new[] { typeof(string) }, null); if (parse == null) { throw new NotSupportedException($"{typeof(TKey)} as TKey in IDictionary is not supported."); } - + while (enumerator.MoveNext()) { var element = (KeyValuePair)enumerator.Current; - instance.Add((TKey)parse.Invoke(null, new[] { (object?) element.Key }), element.Value); + instance.Add((TKey)parse.Invoke(null, new[] { (object?)element.Key }), element.Value); } - + return instance; } @@ -70,8 +70,12 @@ namespace MediaBrowser.Common.Json.Converters var convertedDictionary = new Dictionary(value.Count); foreach (var (k, v) in value) { - convertedDictionary[k?.ToString()] = v; + if (k != null) + { + convertedDictionary[k.ToString()] = v; + } } + JsonSerializer.Serialize(writer, convertedDictionary, options); } } diff --git a/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverterFactory.cs b/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverterFactory.cs index d9795a189..52f360740 100644 --- a/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverterFactory.cs +++ b/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverterFactory.cs @@ -22,18 +22,17 @@ namespace MediaBrowser.Common.Json.Converters /// Conversion ability. public override bool CanConvert(Type typeToConvert) { - if (!typeToConvert.IsGenericType) { return false; } - + // Let built in converter handle string keys if (typeToConvert.GenericTypeArguments[0] == typeof(string)) { return false; } - + // Only support objects that implement IDictionary return typeToConvert.GetInterface(nameof(IDictionary)) != null; } diff --git a/MediaBrowser.Common/Json/JsonDefaults.cs b/MediaBrowser.Common/Json/JsonDefaults.cs index f38e2893e..adc15123b 100644 --- a/MediaBrowser.Common/Json/JsonDefaults.cs +++ b/MediaBrowser.Common/Json/JsonDefaults.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Common.Json /// When changing these options, update /// Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs /// -> AddJellyfinApi - /// -> AddJsonOptions + /// -> AddJsonOptions. /// /// The default options. public static JsonSerializerOptions GetOptions() @@ -33,31 +33,27 @@ namespace MediaBrowser.Common.Json return options; } - + /// - /// Gets CamelCase json options. + /// Gets camelCase json options. /// - public static JsonSerializerOptions CamelCase + /// The camelCase options. + public static JsonSerializerOptions GetCamelCaseOptions() { - get - { - var options = GetOptions(); - options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; - return options; - } + var options = GetOptions(); + options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + return options; } /// /// Gets PascalCase json options. /// - public static JsonSerializerOptions PascalCase + /// The PascalCase options. + public static JsonSerializerOptions GetPascalCaseOptions() { - get - { - var options = GetOptions(); - options.PropertyNamingPolicy = null; - return options; - } + var options = GetOptions(); + options.PropertyNamingPolicy = null; + return options; } } } -- cgit v1.2.3