如何在C#中使用数据注解解决OData反序列化映射空值问题
OData JSON反序列化属性映射失败问题
我从Web API获取了OData REST数据,尝试对以下JSON进行反序列化时,所有属性均映射失败,全部为null。
JSON数据
{ "@odata.context": "https://....crm.dynamics.com/api/data/v9.2/$metadata#msdyn_flow_approvalrequests(statuscode,msdyn_flow_approvalrequestid,statecode,msdyn_flow_approvalrequest_approval(statecode))", "@Microsoft.Dynamics.CRM.totalrecordcount": -1, "@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded": false, "@Microsoft.Dynamics.CRM.globalmetadataversion": "44580385", "value": [ { "@odata.etag": "W/\"44092798\"", "msdyn_flow_approvalrequestidx_owninguserid": "74503F71-FE6B-E911-A81B-000D3A37F60D", "statuscode@OData.Community.Display.V1.FormattedValue": "Active", "statuscode": 1, "msdyn_flow_approvalrequest_approval": { "statecode@OData.Community.Display.V1.FormattedValue": "Active", "statecode": 0 } }, { "@odata.etag": "W/\"44092799\"", "msdyn_flow_approvalrequestidx_owninguserid": "74503F71-FE6B-E911-A81B-000D3A37F60E", "statuscode@OData.Community.Display.V1.FormattedValue": "Active", "statuscode": 1, "msdyn_flow_approvalrequest_approval": { "statecode@OData.Community.Display.V1.FormattedValue": "Active", "statecode": 0 } } ] }
定义的类
public class msdyn_flow_approvalrequests { public string? statecode { get; set; } public msdyn_flow_approvalrequest_approval[]? entity { get; set; } } public class msdyn_flow_approvalrequest_approval { public string? statecode { get; set; } }
反序列化代码
JsonConvert.DeserializeObject<msdyn_flow_approvalrequests>(jsondata);
问题原因及解决方案
核心问题
- 根结构不匹配:JSON核心数据存于
value数组,但你的根类用了entity属性,名称完全不对应;且根类的statecode属性位置错误,它是数组元素的属性,不是根节点属性。 - 类型不兼容:JSON里的
statecode、statuscode是数值类型,但类里定义为string?,类型不匹配导致映射失败。 - 嵌套对象映射缺失:没有针对数组内的完整对象结构定义对应类。
修正后的类定义
// 对应整个JSON根结构 public class ApprovalResponse { // 可选:如需保留OData元数据可添加 [JsonProperty("@odata.context")] public string? ODataContext { get; set; } // 映射JSON的"value"数组 [JsonProperty("value")] public ApprovalRequest[]? ApprovalRequests { get; set; } } // 对应value数组中的单个审批请求对象 public class ApprovalRequest { [JsonProperty("msdyn_flow_approvalrequestidx_owninguserid")] public Guid? OwningUserId { get; set; } [JsonProperty("statuscode")] public int StatusCode { get; set; } [JsonProperty("statuscode@OData.Community.Display.V1.FormattedValue")] public string? StatusCodeFormatted { get; set; } [JsonProperty("msdyn_flow_approvalrequest_approval")] public ApprovalDetail? ApprovalDetail { get; set; } } // 对应嵌套的审批详情对象 public class ApprovalDetail { [JsonProperty("statecode")] public int StateCode { get; set; } [JsonProperty("statecode@OData.Community.Display.V1.FormattedValue")] public string? StateCodeFormatted { get; set; } }
修正后的反序列化代码
var response = JsonConvert.DeserializeObject<ApprovalResponse>(jsondata); // 示例:遍历获取数据 if (response?.ApprovalRequests != null) { foreach (var request in response.ApprovalRequests) { Console.WriteLine($"用户ID: {request.OwningUserId}, 状态: {request.StatusCodeFormatted}"); } }
关键说明
- 用
JsonProperty特性明确JSON属性名与类属性的映射关系,避免命名不一致问题。 - 数值类型的属性需定义为
int而非string,确保类型匹配。 - OData返回的核心数据默认存于
value数组,根类必须包含对应属性才能正确映射。
内容的提问来源于stack exchange,提问作者BizApps
相关产品推荐
相关产品推荐

