.NET 6下反序列化KeyValuePair报错,无法升级至.NET 7如何解决?
.NET 6中System.Text.Json反序列化KeyValuePair失败的解决方案
问题背景
测试代码如下:
[Fact] public void DeserializeKeyValuePair() { string text = "{\"offer\": 12432515239}"; KeyValuePair<string, long> test = JsonSerializer.Deserialize<KeyValuePair<string, long>>(text); }
这段代码在.NET 7中不会崩溃,但反序列化结果为null,不符合预期;在.NET 6中直接抛出异常:
System.Text.Json.JsonException : The JSON value could not be converted to System.Collections.Generic.KeyValuePair`2[System.String,System.Int64]. Path: $.offer | LineNumber: 0 | BytePositionInLine: 9.
由于项目依赖限制无法升级到.NET 7,且希望尽量减少第三方库(如Newtonsoft.Json)的引入,核心需求是反序列化服务器API返回的字典结构。
问题原因
System.Text.Json在.NET 6及更早版本中,对KeyValuePair<TKey, TValue>的反序列化逻辑仅支持包含Key和Value字段的JSON结构(例如{"Key":"offer", "Value":12432515239}),无法直接解析顶层键值对形式的JSON。.NET 7虽做了调整,但仍不能正确处理这种场景,只会返回null而非预期的键值对。
可行解决方案
方案1:直接反序列化为Dictionary类型(推荐)
既然核心需求是处理字典结构,直接将目标类型改为Dictionary<string, long>即可,这是System.Text.Json在.NET 6中原生支持的类型:
[Fact] public void DeserializeDictionary() { string text = "{\"offer\": 12432515239}"; Dictionary<string, long> testDict = JsonSerializer.Deserialize<Dictionary<string, long>>(text); // 如需KeyValuePair,可从字典中提取 KeyValuePair<string, long> kvp = testDict.First(); }
方案2:自定义JsonConverter处理KeyValuePair
如果必须直接反序列化为KeyValuePair<TKey, TValue>,可以编写自定义转换器来适配顶层键值对的JSON结构:
public class KeyValuePairConverter<TKey, TValue> : JsonConverter<KeyValuePair<TKey, TValue>> { public override KeyValuePair<TKey, TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { using var jsonDoc = JsonDocument.ParseValue(ref reader); var property = jsonDoc.RootElement.EnumerateObject().First(); var key = JsonSerializer.Deserialize<TKey>(property.Name, options); var value = JsonSerializer.Deserialize<TValue>(property.Value.GetRawText(), options); return new KeyValuePair<TKey, TValue>(key, value); } public override void Write(Utf8JsonWriter writer, KeyValuePair<TKey, TValue> value, JsonSerializerOptions options) { writer.WriteStartObject(); writer.WritePropertyName(JsonSerializer.Serialize(value.Key, options)); JsonSerializer.Serialize(writer, value.Value, options); writer.WriteEndObject(); } }
使用时在序列化选项中添加转换器:
var jsonOptions = new JsonSerializerOptions(); jsonOptions.Converters.Add(new KeyValuePairConverter<string, long>()); KeyValuePair<string, long> test = JsonSerializer.Deserialize<KeyValuePair<string, long>>(text, jsonOptions);
方案3:安装官方扩展NuGet包
通过安装适配.NET 6的System.Text.Json.Serialization.Metadata或相关扩展包,可以获得更完善的序列化支持,配合配置即可解决问题(这也是用户最终采用的方案)。
内容的提问来源于stack exchange,提问作者julian bechtold
相关产品推荐
相关产品推荐

