C#如何将指定JSON反序列化为KeyValuePair<string, Subscription>?
JSON反序列化为KeyValuePair失败的原因与解决方法
我需要将固定格式的JSON反序列化为KeyValuePair<string, Subscription>,但执行时抛出JsonException无法完成操作。即使改用更宽松的KeyValuePair<string, object>类型,问题依然存在。我纠结于KeyValuePair类型,怀疑可能与字段大小写或其他因素有关,寻求问题原因及解决方法。
复现代码
using System; using System.Collections.Generic; using System.Text.Json; public class Program { public class Subscription { public bool HasRead { get; set; } = true; public string TimeStamp { get; set; } = ""; } public static void Main() { // 该输入格式为固定要求,无法修改 string json = @" { ""305FDF11-25E7-43DE-B09D-DFFC17C79599"": { ""hasRead"": true, ""Timestamp"": ""XXX"" } } "; // 尝试寻找正确的C#反序列化类型 var deser = JsonSerializer.Deserialize<KeyValuePair<string, Subscription>>(json, new JsonSerializerOptions(JsonSerializerDefaults.Web)); // 抛出异常:System.Text.Json.JsonException: //'The JSON value could not be converted to //System.Collections.Generic.KeyValuePair } }
问题原因
- 核心结构不匹配:
KeyValuePair<TKey, TValue>对应的标准JSON结构是{"Key":"你的键", "Value":{...}},但你的输入是一个独立的对象(直接包含键值对),两者结构完全不同,System.Text.Json无法自动转换。 - 字段大小写差异:JSON中的
hasRead、Timestamp和类Subscription的属性HasRead、TimeStamp大小写不一致,默认配置下不会自动映射。
解决方法
方法一:改用Dictionary<string, Subscription>(推荐)
你的JSON本质是键值对集合,Dictionary是最适配这种结构的类型,后续可以轻松取出单个KeyValuePair:
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web) { PropertyNameCaseInsensitive = true // 自动匹配大小写不同的字段 }; var dict = JsonSerializer.Deserialize<Dictionary<string, Subscription>>(json, options); // 获取第一个键值对 var targetKvp = dict.FirstOrDefault();
方法二:自定义转换器强制适配KeyValuePair
如果必须得到KeyValuePair<string, Subscription>类型,可以编写自定义转换器来解析这种结构:
public class KeyValuePairConverter<TKey, TValue> : JsonConverter<KeyValuePair<TKey, TValue>> { public override KeyValuePair<TKey, TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartObject) throw new JsonException("JSON必须是对象格式"); reader.Read(); // 读取第一个键 var key = JsonSerializer.Deserialize<TKey>(ref reader, options); reader.Read(); // 读取对应的值 var value = JsonSerializer.Deserialize<TValue>(ref reader, options); reader.Read(); // 读取对象结束标记 return new KeyValuePair<TKey, TValue>(key, value); } public override void Write(Utf8JsonWriter writer, KeyValuePair<TKey, TValue> value, JsonSerializerOptions options) { writer.WriteStartObject(); JsonSerializer.Serialize(writer, value.Key, options); JsonSerializer.Serialize(writer, value.Value, options); writer.WriteEndObject(); } }
使用转换器的代码:
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web) { PropertyNameCaseInsensitive = true, Converters = { new KeyValuePairConverter<string, Subscription>() } }; var deser = JsonSerializer.Deserialize<KeyValuePair<string, Subscription>>(json, options);
内容的提问来源于stack exchange,提问作者jeancallisti
相关产品推荐
相关产品推荐

