aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverterFactory.cs
blob: 52f3607401f8c3c6d4aacaa737c188cc118ca498 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#nullable enable

using System;
using System.Collections;
using System.Globalization;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace MediaBrowser.Common.Json.Converters
{
    /// <summary>
    /// https://github.com/dotnet/runtime/issues/30524#issuecomment-524619972.
    /// TODO This can be removed when System.Text.Json supports Dictionaries with non-string keys.
    /// </summary>
    internal sealed class JsonNonStringKeyDictionaryConverterFactory : JsonConverterFactory
    {
        /// <summary>
        /// Only convert objects that implement IDictionary and do not have string keys.
        /// </summary>
        /// <param name="typeToConvert">Type convert.</param>
        /// <returns>Conversion ability.</returns>
        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;
        }

        /// <summary>
        /// Create converter for generic dictionary type.
        /// </summary>
        /// <param name="typeToConvert">Type to convert.</param>
        /// <param name="options">Json serializer options.</param>
        /// <returns>JsonConverter for given type.</returns>
        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
        {
            var converterType = typeof(JsonNonStringKeyDictionaryConverter<,>)
                .MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1]);
            var converter = (JsonConverter)Activator.CreateInstance(
                converterType,
                BindingFlags.Instance | BindingFlags.Public,
                null,
                null,
                CultureInfo.CurrentCulture);
            return converter;
        }
    }
}