如何将含动态键的JSON响应反序列化为C#类或可用结果对象
C# 反序列化多层动态键汽车金融API响应方案
这类键名随请求参数动态变化的嵌套JSON,不要用代码生成工具生成固定属性类,直接用Dictionary<string, T>承接动态键层级即可,Newtonsoft.Json和System.Text.Json均原生支持字典结构的反序列化,具体实现步骤如下:
1. 定义核心强类型模型
首先定义最内层数组中固定结构的贷款方案实体,兼容HP、PCP两种产品的字段,类型不固定的字段用object承接避免反序列化报错:
/// <summary> /// 汽车金融方案详情 /// </summary> public class FinanceProduct { public decimal balance { get; set; } public decimal first { get; set; } public decimal regular { get; set; } public decimal final { get; set; } public decimal total { get; set; } public decimal charges { get; set; } public decimal apr { get; set; } public decimal apr_nofees { get; set; } public int term { get; set; } public decimal flat { get; set; } // PCP专属字段,HP产品下返回null public decimal? rv { get; set; } public decimal? rv_interest { get; set; } public decimal? charges_ex_rv { get; set; } public string fee_front { get; set; } public string fee_back { get; set; } public int fee_spread { get; set; } // 该字段存在字符串/数值两种格式,用object承接 public object @ref { get; set; } public int ho { get; set; } public int ho_a { get; set; } public int sb { get; set; } public string id { get; set; } public string product_name { get; set; } // 该字段存在布尔值/字符串两种格式,用object承接 public object excess_mileage { get; set; } }
再定义外层响应结构,所有动态键的嵌套层级全部用字典实现:
public class FinanceApiResponse { public bool success { get; set; } public FinanceResponseData data { get; set; } } public class FinanceResponseData { // 动态键层级顺序:车辆价格 -> 贷款期限(月) -> 首付比例(%) -> 年行驶里程 -> 对应方案列表 public Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, List<FinanceProduct>>>>> hp { get; set; } public Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, List<FinanceProduct>>>>> pcp { get; set; } public int count { get; set; } public int taken { get; set; } }
2. 执行反序列化
两种主流JSON库的调用方式如下:
- 使用Newtonsoft.Json:
var result = JsonConvert.DeserializeObject<FinanceApiResponse>(rawJsonText);
- 使用.NET内置System.Text.Json:
var result = JsonSerializer.Deserialize<FinanceApiResponse>(rawJsonText, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
3. 字段读取示例
反序列化完成后,直接通过传入的请求参数作为字典Key读取对应数据即可,例如读取示例中58995车价、48期、40%首付、年里程9000的HP方案:
// 读取HP第一个方案 var hpPlan = result.data.hp["58995"]["48"]["40"]["9000"][0]; decimal hpMonthlyPayment = hpPlan.regular; decimal hpTotalCost = hpPlan.total; // 读取PCP第一个方案 var pcpPlan = result.data.pcp["58995"]["48"]["40"]["9000"][0]; decimal pcpResidualValue = pcpPlan.rv ?? 0;
注意:如果请求参数本身是数值类型,读取时直接ToString()作为字典Key即可;如果需要对类型不固定的
ref、excess_mileage字段做强类型转换,可以根据当前读取的是HP还是PCP产品做显式类型转换,也可以自定义JsonConverter实现自动转换。
内容的提问来源于stack exchange,提问作者Mr. Waqas
相关产品推荐
相关产品推荐

