JsonNonStringKeyDictionaryConverterFactory.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #nullable enable
  2. using System;
  3. using System.Collections;
  4. using System.Globalization;
  5. using System.Reflection;
  6. using System.Text.Json;
  7. using System.Text.Json.Serialization;
  8. namespace MediaBrowser.Common.Json.Converters
  9. {
  10. /// <summary>
  11. /// https://github.com/dotnet/runtime/issues/30524#issuecomment-524619972.
  12. /// TODO This can be removed when System.Text.Json supports Dictionaries with non-string keys.
  13. /// </summary>
  14. internal sealed class JsonNonStringKeyDictionaryConverterFactory : JsonConverterFactory
  15. {
  16. /// <summary>
  17. /// Only convert objects that implement IDictionary and do not have string keys.
  18. /// </summary>
  19. /// <param name="typeToConvert">Type convert.</param>
  20. /// <returns>Conversion ability.</returns>
  21. public override bool CanConvert(Type typeToConvert)
  22. {
  23. if (!typeToConvert.IsGenericType)
  24. {
  25. return false;
  26. }
  27. // Let built in converter handle string keys
  28. if (typeToConvert.GenericTypeArguments[0] == typeof(string))
  29. {
  30. return false;
  31. }
  32. // Only support objects that implement IDictionary
  33. return typeToConvert.GetInterface(nameof(IDictionary)) != null;
  34. }
  35. /// <summary>
  36. /// Create converter for generic dictionary type.
  37. /// </summary>
  38. /// <param name="typeToConvert">Type to convert.</param>
  39. /// <param name="options">Json serializer options.</param>
  40. /// <returns>JsonConverter for given type.</returns>
  41. public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
  42. {
  43. var converterType = typeof(JsonNonStringKeyDictionaryConverter<,>)
  44. .MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1]);
  45. var converter = (JsonConverter)Activator.CreateInstance(
  46. converterType,
  47. BindingFlags.Instance | BindingFlags.Public,
  48. null,
  49. null,
  50. CultureInfo.CurrentCulture);
  51. return converter;
  52. }
  53. }
  54. }