如何将SAP Netweaver Gateway返回的Header+Item JSON反序列化为嵌套模型
解决OData嵌套结构的Json反序列化问题
这种情况我之前也碰到过——Netweaver Gateway返回的OData格式里,嵌套集合都会被包裹在results字段里,你的模型肯定是没对应上这个层级结构,所以才反序列化失败。
先看你给出的JSON:工单明细是在WorkPermit_hdr_itm_nav下的results数组里,不是直接的数组对象。所以要解决问题,得调整模型类,正确映射这个层级。
第一步:定义匹配的模型类
根据返回的JSON结构,我们需要四层模型(外层OData容器、工单头、明细集合容器、工单明细),我把所有字段都列全了,你可以按需删减:
// 外层OData响应容器,用来包裹d节点 public class ODataResponse<T> { [JsonProperty("d")] public T Data { get; set; } } // 工单头模型 public class WorkPermitHdr { [JsonProperty("__metadata")] public Metadata Metadata { get; set; } [JsonProperty("WpNr")] public string WpNr { get; set; } [JsonProperty("WoNr")] public string WoNr { get; set; } [JsonProperty("Desc1")] public string Desc1 { get; set; } [JsonProperty("Desc2")] public string Desc2 { get; set; } [JsonProperty("Loc1")] public string Loc1 { get; set; } [JsonProperty("Loc2")] public string Loc2 { get; set; } [JsonProperty("Execution")] public string Execution { get; set; } [JsonProperty("ExecDept")] public string ExecDept { get; set; } [JsonProperty("ExecComp")] public string ExecComp { get; set; } [JsonProperty("SupExec")] public string SupExec { get; set; } [JsonProperty("SupExecTel")] public string SupExecTel { get; set; } [JsonProperty("VpkInstr")] public string VpkInstr { get; set; } [JsonProperty("VpkInstrTel")] public string VpkInstrTel { get; set; } [JsonProperty("WorkSup")] public string WorkSup { get; set; } [JsonProperty("WorkSupTel")] public string WorkSupTel { get; set; } [JsonProperty("Status")] public string Status { get; set; } [JsonProperty("ValidFrom")] public DateTime? ValidFrom { get; set; } [JsonProperty("ValidTo")] public DateTime? ValidTo { get; set; } [JsonProperty("CreateUser")] public string CreateUser { get; set; } [JsonProperty("ChangeUser")] public string ChangeUser { get; set; } // 关键:嵌套明细的集合容器,对应JSON里的WorkPermit_hdr_itm_nav [JsonProperty("WorkPermit_hdr_itm_nav")] public WorkPermitItemCollection ItemCollection { get; set; } } // 明细集合容器,用来包裹results数组 public class WorkPermitItemCollection { [JsonProperty("results")] public List<WorkPermitItm> Items { get; set; } } // 工单明细模型 public class WorkPermitItm { [JsonProperty("__metadata")] public Metadata Metadata { get; set; } [JsonProperty("WpNr")] public string WpNr { get; set; } [JsonProperty("WoOper")] public string WoOper { get; set; } [JsonProperty("Desc")] public string Desc { get; set; } [JsonProperty("CreateUser")] public string CreateUser { get; set; } [JsonProperty("ChangeUser")] public string ChangeUser { get; set; } } // 可选:如果不需要metadata字段,可以直接删掉这个类,Json.NET会自动忽略未知字段 public class Metadata { [JsonProperty("id")] public string Id { get; set; } [JsonProperty("uri")] public string Uri { get; set; } [JsonProperty("type")] public string Type { get; set; } }
第二步:执行反序列化
用你熟悉的JsonConvert.DeserializeObject方法,把JSON字符串转换成模型即可:
string jsonString = "你的OData返回JSON字符串"; var oDataResponse = JsonConvert.DeserializeObject<ODataResponse<WorkPermitHdr>>(jsonString); // 取出工单头和明细列表 WorkPermitHdr workPermitHeader = oDataResponse.Data; List<WorkPermitItm> workPermitItems = workPermitHeader.ItemCollection.Items;
为什么之前失败?
大概率是你之前把WorkPermit_hdr_itm_nav直接定义成了List<WorkPermitItm>,但JSON里这个字段对应的是一个包含results数组的对象,不是数组本身。必须通过中间的WorkPermitItemCollection类来映射这个层级,才能正确解析出嵌套的明细数据。
另外要注意:所有JsonProperty的名称必须和JSON里的键完全一致(包括大小写和下划线),否则Json.NET会找不到对应的字段,导致属性值为null。
内容的提问来源于stack exchange,提问作者Kevin Lievens
相关产品推荐
相关产品推荐

