C#中反序列化含动态属性名的Newtonsoft JSON数据
解决动态键JSON到C#对象的反序列化问题
你的问题核心在于JSON响应里的result字段是一个带有动态键(RITM编号)的对象,而你的C#模型里result直接定义为RITMDetails类型,两者结构不匹配,导致常规反序列化无法生效。下面给你两种简单可行的解决方案:
方案一:修改模型使用字典处理动态键
这是最直接的方法,只需要把result的类型从RITMDetails改成Dictionary<string, RITMDetails>,让字典来容纳那个动态的RITM编号键:
public class RITMGETRequestResponse { // 用字典接收动态键值对 public Dictionary<string, RITMDetails> result { get; set; } public class RITMDetails { public string business_justification { get; set; } public string number { get; set; } public string requested_for { get; set; } public string stage { get; set; } public string state { get; set; } public string Sys_ID { get; set; } public string var_name_arr { get; set; } public string Contoso_business_justification { get; set; } public string Contoso_catalog_item_footer { get; set; } public string Contoso_requested_for { get; set; } public string Contoso_sc_Appname { get; set; } public string Contoso_Sc_Contactinfo { get; set; } public string Contoso_sc_Description { get; set; } public string Contoso_sc_Purposeofthef5request { get; set; } public string Contoso_special_instructions { get; set; } } }
然后用JSON序列化库完成反序列化,再提取字典里的唯一值(看起来你的JSON里result下只有一个RITM条目):
使用Newtonsoft.Json的代码:
string jsonResponse = @"{""result"": { ""RITM2572913"": { ""number"": ""RITM2572913"", ""state"": ""1"", ... } }}"; // 你的完整JSON字符串 var response = JsonConvert.DeserializeObject<RITMGETRequestResponse>(jsonResponse); // 获取RITM详情对象 var ritmDetails = response.result.Values.FirstOrDefault(); if (ritmDetails != null) { string sysId = ritmDetails.Sys_ID; string number = ritmDetails.number; // 其他属性都可以直接访问 }
使用System.Text.Json的代码:
using System.Text.Json; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, // 忽略大小写匹配属性 WriteIndented = true }; var response = JsonSerializer.Deserialize<RITMGETRequestResponse>(jsonResponse, options); var ritmDetails = response.result.Values.FirstOrDefault(); if (ritmDetails != null) { // 访问所需属性 }
方案二:不修改模型,先反序列化到动态对象再映射
如果你不想修改原有的模型结构,可以先把JSON反序列化为动态对象,再把动态对象里的详情部分转换为RITMDetails:
dynamic dynamicResponse = JsonConvert.DeserializeObject(jsonResponse); // 遍历result下的动态属性(这里只有一个) foreach (var ritmEntry in dynamicResponse.result) { // 把动态值序列化为JSON字符串,再反序列化为RITMDetails var ritmDetails = JsonConvert.DeserializeObject<RITMGETRequestResponse.RITMDetails>( JsonConvert.SerializeObject(ritmEntry.Value) ); // 访问属性 string sysId = ritmDetails.Sys_ID; }
为什么原模型无法生效?
原JSON的result结构是:
"result": { "RITM2572913": { /* 详情对象 */ } }
它是一个包含单个键值对的对象,而你的原模型里result直接是RITMDetails类型,相当于期望result就是详情对象本身,结构不匹配,所以反序列化会失败。
内容的提问来源于stack exchange,提问作者SavindraSingh
相关产品推荐
相关产品推荐

