You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:05:39