C#反序列化嵌套JSON时无法通过Dictionary访问嵌套displayName属性
问题根因
你将fields定义为Dictionary<string, object>类型,使用JsonConvert.DeserializeObject反序列化时:
- 普通的字符串、数字类一级属性会被转换为对应C#基础类型,直接取值没问题
- 像
System.AssignedTo这类嵌套JSON对象,默认会被Newtonsoft.Json反序列化为JObject类型,但因为你字典的值类型声明为object,编译阶段编译器会把取出来的值识别为object类型,而object类型没有定义[string]索引器,所以直接写fields["System.AssignedTo"]["displayName"]会报编译错误。
解决方法
选下面任意一种方案即可:
方案1:最小改动,显式转换类型
把取出的System.AssignedTo值显式转为JObject,再访问内部属性即可,不需要修改原有模型定义:
@((WorkItemDetailResponse.fields["System.AssignedTo"] as JObject)?["displayName"])
如果要做更稳妥的空值兼容,可以把取值逻辑单独写在代码块里:
@{ var assignedToObj = WorkItemDetailResponse.fields["System.AssignedTo"] as JObject; string assignedUserName = assignedToObj?["displayName"]?.ToString() ?? "未指派"; } @assignedUserName
注意:用这个方案需要保证你的项目已经引入了
Newtonsoft.Json(也就是你现在用的JsonConvert所在的包),JObject是这个包里的类型,不需要额外装其他依赖。
方案2:定义强类型模型(推荐)
如果接口返回的字段结构固定,直接定义对应强类型类替代Dictionary<string, object>,既不需要做类型转换,编译时还能检查属性名是否写错,后续维护更方便:
// 定义模型时用JsonProperty映射JSON里带点的属性名 public class WorkItemDetail { public int id { get; set; } public int rev { get; set; } public WorkItemFields fields { get; set; } } public class WorkItemFields { [JsonProperty("System.Url")] public string Url { get; set; } [JsonProperty("System.Type")] public string Type { get; set; } [JsonProperty("System.State")] public string State { get; set; } [JsonProperty("System.AssignedTo")] public AssignedUser AssignedTo { get; set; } } public class AssignedUser { public string displayName { get; set; } }
反序列化代码不用改,Razor里直接用属性访问取值即可:
@WorkItemDetailResponse.id @WorkItemDetailResponse.fields.Type @WorkItemDetailResponse.fields.State @WorkItemDetailResponse.fields.AssignedTo.displayName
内容的提问来源于stack exchange,提问作者elektra
相关产品推荐
相关产品推荐

