如何将含动态键的Zoho Forms响应JSON反序列化为C#对象
处理Zoho Forms动态键JSON的C#反序列化方案
问题分析
你要处理的Zoho Forms响应JSON核心特点是:result数组内的每个对象都包含唯一动态键,该键对应的值是嵌套的响应项数组(包含EmailID和CreatedTime)。原代码存在重复序列化反序列化、硬编码动态键的问题,无法通用处理所有动态键场景。
示例JSON结构
{ "result": [ { "726468000000236142": [ { "EmailID": "tiaburmen@zylker.com", "CreatedTime": "1671092494538" } ] }, { "726468000000236143": [ { "EmailID": "tiaburmen1@zylker.com", "CreatedTime": "16710192494538" } ] } ] }
解决方案
方法1:嵌套字典直接反序列化(最直观)
定义对应实体类,直接用嵌套字典承载动态键:
// 响应项实体类 public class FormResponseItem { public string EmailID { get; set; } public string CreatedTime { get; set; } // 若需要数值类型可改为long } // 顶层响应类 public class ZohoFormsResponse { public List<Dictionary<string, List<FormResponseItem>>> Result { get; set; } }
反序列化并遍历数据:
var response = JsonConvert.DeserializeObject<ZohoFormsResponse>(jsonString); foreach (var dictItem in response.Result) { // 遍历每个动态键值对(每个dictItem仅含一个键) foreach (var kvp in dictItem) { string dynamicKey = kvp.Key; foreach (var item in kvp.Value) { Console.WriteLine($"动态键:{dynamicKey},邮箱:{item.EmailID},创建时间:{item.CreatedTime}"); } } }
方法2:用JsonExtensionData特性简化类结构
通过JsonExtensionData将动态键统一存入字典,类结构更简洁:
public class FormResponseItem { public string EmailID { get; set; } public string CreatedTime { get; set; } } public class ResultItem { // 自动捕获所有未匹配的动态键 [JsonExtensionData] public Dictionary<string, JToken> DynamicData { get; set; } } public class ZohoFormsResponse { public List<ResultItem> Result { get; set; } }
处理代码:
var response = JsonConvert.DeserializeObject<ZohoFormsResponse>(jsonString); foreach (var resultItem in response.Result) { foreach (var kvp in resultItem.DynamicData) { var items = kvp.Value.ToObject<List<FormResponseItem>>(); foreach (var item in items) { Console.WriteLine($"动态键:{kvp.Key},邮箱:{item.EmailID}"); } } }
方法3:动态对象+LINQ快速处理(无需定义类)
如果不想定义实体类,可直接用dynamic结合JObject提取数据:
var finalResult = JsonConvert.DeserializeObject<dynamic>(jsonString); foreach (var item in finalResult.result) { var jObj = JObject.FromObject(item); // 获取唯一的动态键值对 var prop = jObj.Properties().First(); var responseItems = prop.Value.ToObject<List<dynamic>>(); foreach (var respItem in responseItems) { Console.WriteLine($"动态键:{prop.Name},邮箱:{respItem.EmailID},创建时间:{respItem.CreatedTime}"); } }
原代码问题修正点
- 移除重复序列化反序列化:无需将
item转成JSON再转回字典,直接转JObject或Dictionary即可。 - 避免硬编码动态键:通过遍历字典/属性的方式获取动态键,适配所有场景。
- 正确调用
SelectToken:若要使用该方法,需先将字典值转为JToken类型,例如:((JToken)dictionary[dynamicKey]).SelectToken("EmailID")。
内容的提问来源于stack exchange,提问作者Saravanan Arunagiri
相关产品推荐
相关产品推荐

