You need to enable JavaScript to run this app. C# 使用 Newtonsoft.Json 结合 Dictionary/List 创建无硬编码属性名的 DTO
优惠活动
大模型
产品
解决方案
定价
更多

C# 使用 Newtonsoft.Json 结合 Dictionary/List 创建无硬编码属性名的 DTO

动态键硬编码消除方案

核心思路

针对StorageData类下无固定枚举值的数字动态键,直接复用你已经验证可用的Dictionary承接逻辑,不需要硬编码"1""2"这类属性名,也不需要通过多JsonProperty特性做匹配。

原实现待优化点

当前StorageData类中硬编码的两个属性存在明显维护成本:

[JsonProperty(PropertyName = "2")]
public DataInfo DataDetails2 { get; set; }

[JsonProperty(PropertyName = "1")]
public DataInfo DataDetails { get; set; }
  • 后续JSON结构新增"3""4"等数字键时,必须手动新增属性加JsonProperty特性,扩展性极差
  • 尝试通过JsonPropertyTagNames = new Object[]{"1","2"}给单个属性绑定多个键名的写法不生效,是因为Newtonsoft.Json本身不支持单个CLR属性匹配多个动态键名,这类场景必须用字典结构承接。

修正后的实现逻辑

直接将StorageData类中的两个硬编码属性替换为字典结构,Newtonsoft.Json会自动把类结构中没有对应静态属性的所有键值对,映射到该字典属性中,和外层data字段的反序列化逻辑完全一致:

public class StorageData
{
    /// <summary>
    /// 自动收集所有数字格式的动态键值对
    /// 键为JSON中的数字字符串("1"/"2"/"3"...),值为对应DataInfo实例
    /// </summary>
    public Dictionary<string, DataInfo> DataDetailsCollection { get; set; } = new();
}

注意:该字典属性不需要指定固定的JsonProperty名称,Newtonsoft.Json会自动扫描所有未匹配到静态属性的键做映射。

适配示例JSON的完整DTO代码

using System.Collections.Generic;
using Newtonsoft.Json;

namespace TestModels.Dto
{
    /// <summary>
    /// 顶层响应结构
    /// </summary>
    public class StorageData_v1
    {
        /// <summary>
        /// API版本号
        /// </summary>
        [JsonProperty(PropertyName = "apiVersion")]
        public string ApiVersion { get; set; }

        /// <summary>
        /// 按业务编号分类的存储数据集合,外层键为业务编号字符串
        /// </summary>
        [JsonProperty(PropertyName = "data")]
        public Dictionary<string, StorageData> Data { get; set; }
    }

    /// <summary>
    /// 单个业务编号下的存储数据集合
    /// </summary>
    public class StorageData
    {
        /// <summary>
        /// 按动态数字键收集的详情数据
        /// </summary>
        public Dictionary<string, DataInfo> DataDetailsCollection { get; set; } = new();
    }

    /// <summary>
    /// 单条数据详情
    /// </summary>
    public class DataInfo
    {
        [JsonProperty(PropertyName = "juris")]
        public string Jurisdiction { get; set; }

        [JsonProperty(PropertyName = "entity")]
        public string Entity { get; set; }

        [JsonProperty(PropertyName = "instance")]
        public string Instance { get; set; }

        [JsonProperty(PropertyName = "calcJobId")]
        public string CalcJobId { get; set; }

        [JsonProperty(PropertyName = "formIndex")]
        public string FormIndex { get; set; }

        [JsonProperty(PropertyName = "ReturnId")]
        public string ReturnId { get; set; }

        [JsonProperty(PropertyName = "storage")]
        public Storage Storage { get; set; }
    }

    /// <summary>
    /// Base64存储数据集合
    /// </summary>
    public class Storage
    {
        [JsonProperty(PropertyName = "$podRawBase64")]
        public string PodRawBase64 { get; set; }

        [JsonProperty(PropertyName = "$podDbkRawBase64")]
        public string PodDbkRawBase64 { get; set; }
    }
}

验证结果

用提供的示例JSON测试反序列化时,可实现全字段无丢失映射:

  • 顶层apiVersion字段正常绑定到对应属性
  • data节点下的"738""463"键自动存入StorageData_v1.Data字典
  • 每个业务节点下的"1"键自动存入StorageData.DataDetailsCollection字典,对应值正常反序列化为DataInfo实例
  • storage节点下的$podRawBase64、$podDbkRawBase64字段全部正常映射,不存在硬编码漏配问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 22:06:03