From 30609c848bdab2a93a44b8fc8d2bd58042ab795b Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 11 Jun 2020 10:51:47 -0600 Subject: Add MessageId to websocket message, add JsonNonStringKeyDictionaryConverter --- .../JsonNonStringKeyDictionaryConverter.cs | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverter.cs (limited to 'MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverter.cs') diff --git a/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverter.cs b/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverter.cs new file mode 100644 index 000000000..683e23df8 --- /dev/null +++ b/MediaBrowser.Common/Json/Converters/JsonNonStringKeyDictionaryConverter.cs @@ -0,0 +1,79 @@ +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MediaBrowser.Common.Json.Converters +{ + /// + /// Converter for Dictionaries without string key. + /// TODO This can be removed when System.Text.Json supports Dictionaries with non-string keys. + /// + /// Type of key. + /// Type of value. + internal sealed class JsonNonStringKeyDictionaryConverter : JsonConverter> + { + /// + /// Read JSON. + /// + /// The Utf8JsonReader. + /// The type to convert. + /// The json serializer options. + /// Typed dictionary. + /// Not supported. + public override IDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var convertedType = typeof(Dictionary<,>).MakeGenericType(typeof(string), typeToConvert.GenericTypeArguments[1]); + var value = JsonSerializer.Deserialize(ref reader, convertedType, options); + var instance = (Dictionary)Activator.CreateInstance( + typeToConvert, + BindingFlags.Instance | BindingFlags.Public, + null, + null, + 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) }, + 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); + } + + return instance; + } + + /// + /// Write dictionary as Json. + /// + /// The Utf8JsonWriter. + /// The dictionary value. + /// The Json serializer options. + public override void Write(Utf8JsonWriter writer, IDictionary value, JsonSerializerOptions options) + { + var convertedDictionary = new Dictionary(value.Count); + foreach (var (k, v) in value) + { + convertedDictionary[k?.ToString()] = v; + } + + JsonSerializer.Serialize(writer, convertedDictionary, options); + } + } +} -- cgit v1.2.3