The KeyValuePairConverter<TKey, TValue> is an special case that uses an internal converter that inherits from SmallObjectWithParameterizedConstructorConverter, and that converter validates that the only valid properties are Key and Value.
public static void DeserializeIdOnKVP()
{
string json = @"
{
""$id"": ""1"",
""Key"": ""TestKey"",
""Value"": ""TestValue""
}";
var opts = new JsonSerializerOptions
{
ReferenceHandling = ReferenceHandling.Preserve
};
KeyValuePair<string, string> kvp = JsonSerializer.Deserialize<KeyValuePair<string, string>>(json, opts);
Console.WriteLine(kvp.Key);
}
Therefore when a metadata property $id is also present in the JSON object, the deserializer throws the following, even when the ReferenceHandler feature is set:
System.Text.Json.JsonException : The JSON value could not be converted to System.Collections.Generic.KeyValuePair`2[System.String,System.String]. Path: $ | LineNumber: 2 | BytePositionInLine: 22.
While other types that also use SmallObjectWithParameterizedConstructorConverter throw the following on ReferenceHandler scenarios:
System.NotSupportedException: Reference metadata is not honored when deserializing types using parameterized constructors. See type 'System.Text.Json.Serialization.Tests.ConstructorTests+Employee'. Path: $.$id | LineNumber: 0 | BytePositionInLine: 7.