using System.Collections.Generic;
using System.Text.Json.Serialization;
public class KeyValuePairConverter<TKey, TValue> : JsonConverter<Dictionary<TKey, TValue>>
public override bool CanConvert(Type typeToConvert)
if (base.CanConvert(typeToConvert))
if (typeToConvert.GetGenericTypeDefinition() == typeof(IDictionary<,>) ||
typeToConvert.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary<,>))
var genericArguments = typeToConvert.GetGenericArguments();
return genericArguments[0] == typeof(TKey) && genericArguments[1] == typeof(TValue);
public override Dictionary<TKey, TValue>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException("Expected the JSON object to start with an array.");
var keyPairConverter = (JsonConverter<KeyValuePair<TKey, TValue>>)options.GetConverter(typeof(KeyValuePair<TKey, TValue>));
var dictionary = new Dictionary<TKey, TValue>();
if (reader.TokenType == JsonTokenType.EndArray)
var pair = keyPairConverter.Read(ref reader, typeof(KeyValuePair<TKey, TValue>), options);
throw new JsonException("Failed to read the key-value pair from JSON.");
dictionary.Add(pair.Key, pair.Value);
throw new JsonException("Failed to read the JSON object.");
public override void Write(Utf8JsonWriter writer, Dictionary<TKey, TValue> value, JsonSerializerOptions options)
writer.WriteStartArray();
var keyPairConverter = (JsonConverter<KeyValuePair<TKey, TValue>>)options.GetConverter(typeof(KeyValuePair<TKey, TValue>));
foreach (var pair in value)
keyPairConverter.Write(writer, pair, options);