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

C#使用自定义类与Dictionary实现JSON序列化反序列化问题求助

C# JSON动态字段序列化反序列化解决方案

问题根因

你当前定义的类结构与目标JSON结构不匹配:filter_keys类将shortDescription这类动态过滤字段嵌套在properties字典节点下,但实际JSON中动态字段与notes、group等固定字段同级,没有外层properties包裹,因此反序列化无法正确映射。

解决方案:使用JsonExtensionData特性

该特性是序列化库专门为「固定字段+动态字段混合」的JSON场景设计的:

  • 序列化时:字典内的键值对会自动提升到JSON根级,和固定字段平级
  • 反序列化时:未匹配到固定字段的键值对会自动存入该字典

你只需给properties字段添加对应序列化库的特性即可,调整后的类结构如下:

using System.Collections.Generic;
// 使用System.Text.Json的话引入下面的命名空间
using System.Text.Json.Serialization;
// 使用Newtonsoft.Json的话引入下面的命名空间
// using Newtonsoft.Json;

public class filter_keys
{
    public string notes { get; set; }
    public string group { get; set; }
    public string assigned { get; set; }
    
    // System.Text.Json的特性
    [JsonExtensionData]
    // Newtonsoft.Json的特性
    // [JsonExtensionData]
    public Dictionary<string, filter_properties> properties { get; set; } = new Dictionary<string, filter_properties>();
}

public class filter_properties
{
    public bool contains { get; set; }
    public bool equals { get; set; }
    public bool startsWith { get; set; }
    public string value { get; set; }
}

可选优化:添加便捷访问属性

如果需要直接通过点语法访问shortDescription、description这类常用字段,不需要每次查字典,可以给filter_keys加两个计算属性,不影响序列化反序列化结果:

public class filter_keys
{
    public string notes { get; set; }
    public string group { get; set; }
    public string assigned { get; set; }
    
    [JsonExtensionData]
    public Dictionary<string, filter_properties> properties { get; set; } = new Dictionary<string, filter_properties>();

    // 便捷访问shortDescription,不存在返回null
    public filter_properties shortDescription 
    {
        get => properties.TryGetValue(nameof(shortDescription), out var prop) ? prop : null;
        set => properties[nameof(shortDescription)] = value;
    }

    // 便捷访问description,不存在返回null
    public filter_properties description 
    {
        get => properties.TryGetValue(nameof(description), out var prop) ? prop : null;
        set => properties[nameof(description)] = value;
    }
}

使用示例

构造并序列化对象

var filter = new filter_keys
{
    notes = "Something bad happened",
    group = "some group",
    assigned = "to me",
    // 直接给便捷属性赋值
    shortDescription = new filter_properties 
    { 
        startsWith = true, 
        value = "some text" 
    },
    description = new filter_properties 
    { 
        contains = true, 
        value = "some more text" 
    }
};
// 手动添加其他动态字段
filter.properties.Add("createdAfter", new filter_properties { value = "2021-08-17" });

// System.Text.Json序列化
string json = JsonSerializer.Serialize(filter, new JsonSerializerOptions { WriteIndented = true });
// Newtonsoft.Json序列化
// string json = JsonConvert.SerializeObject(filter, Formatting.Indented);

输出的JSON结构和你给出的示例完全一致。

反序列化并访问属性

// System.Text.Json反序列化
filter_keys filterObj = JsonSerializer.Deserialize<filter_keys>(json);
// Newtonsoft.Json反序列化
// filter_keys filterObj = JsonConvert.DeserializeObject<filter_keys>(json);

// 校验shortDescription是否存在并访问子属性
if (filterObj.shortDescription != null)
{
    bool isStartsWith = filterObj.shortDescription.startsWith;
    string descValue = filterObj.shortDescription.value;
}

// 校验任意动态字段是否存在
if (filterObj.properties.TryGetValue("createdAfter", out var createdProp))
{
    string dateValue = createdProp.value;
}

内容的提问来源于stack exchange,提问作者Autonomic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:51:01