You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:JsonConvert.DeserializeObject获取Task List返回Null(API结构变更)

问题描述

我研究这个问题好几个小时了,还是没法完成Web API调用响应的反序列化。之前的代码运行正常,但API更新后接口结构变了——新增了Order层级,导致现有代码失效。我需要从API返回结果里提取Tasks列表来处理,Postman返回的API响应结构如下:

{"Version": 1,"Result": "Success","Data": {"Order": {"Oid": "f3a3afa9-ac2b-4914-b3cb-585c761f2dfb","Did": 265532,"Tasks": [{"Oid": "af82ce50-0587-4752-ba3b-d60dbfebe041","CreatedOn": "2023-05-19T02:24:55.437Z","ChangedOn": "2023-05-19T02:45:26.28Z","Description": "","Comment": "","IsStarted": false,"ScheduledOn": "2023-05-19T12:14:51.507","ProductionDeadline": "2023-05-21T16:00:00","ScheduledStart": "2023-05-19T11:56:00","ScheduledEnd": "2023-05-19T12:04:00","RealStart": "0001-01-01T00:00:00","RealEnd": "0001-01-01T00:00:00","OrderItemPartsCount": 27,"CalculatedSeconds": "120","IdleSeconds": "0","ScheduledSeconds": 480,"RealSeconds": 0,"PercentComplete": 0,"HasFinishedItems": false,"IsCustomTask": false,"AppointmentType": "OrderSpecificAppointment","Station": {"_Value": "Centurio","oid": "f7f3c5fe-49f0-4a9a-b366-29c4ab990fc7"},"MasterTask": {"_Value": "","oid": "179212f4-ff0e-465d-962c-51b7da711bb7"}},{"Oid": "72b6a0ba-cbc2-4f9b-9372-86805d40f7e3","CreatedOn": "2023-05-19T02:24:55.437Z","ChangedOn": "2023-05-19T02:25:28.37Z","Description": "","Comment": "","IsStarted": false,"ScheduledOn": "2023-05-19T11:54:55.437","ProductionDeadline": "2023-05-21T16:00:00","ScheduledStart": "2023-05-19T12:11:00","ScheduledEnd": "2023-05-19T13:10:00","RealStart": "0001-01-01T00:00:00","RealEnd": "0001-01-01T00:00:00","OrderItemPartsCount": 27,"CalculatedSeconds": "3540","IdleSeconds": "0","ScheduledSeconds": 3540,"RealSeconds": 0,"PercentComplete": 0,"HasFinishedItems": false,"IsCustomTask": false,"AppointmentType": "OrderSpecificAppointment","Station": {"_Value": "Twinmatic","oid": "d92a32c3-0763-49d7-a8eb-77ea68afa311"}}]}},"Details": ""}

旧版本的API响应里没有Order元素,求帮忙说明怎么把Tasks获取成List来做后续处理。


解决方案

方法1:强类型解析(定义匹配新结构的实体类)

这种方式更安全、易维护,适合长期项目。根据新的API响应结构创建对应实体类,直接反序列化后提取Tasks:

实体类定义(以C#为例)

// 最外层响应容器
public class ApiResponse
{
    public int Version { get; set; }
    public string Result { get; set; }
    public ApiData Data { get; set; }
    public string Details { get; set; }
}

public class ApiData
{
    public Order Order { get; set; }
}

public class Order
{
    public string Oid { get; set; }
    public int Did { get; set; }
    public List<TaskItem> Tasks { get; set; }
}

// Task实体类,包含所有需要的字段
public class TaskItem
{
    public string Oid { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime ChangedOn { get; set; }
    public string Description { get; set; }
    public string Comment { get; set; }
    public bool IsStarted { get; set; }
    public DateTime ScheduledOn { get; set; }
    public DateTime ProductionDeadline { get; set; }
    public DateTime ScheduledStart { get; set; }
    public DateTime ScheduledEnd { get; set; }
    public DateTime RealStart { get; set; }
    public DateTime RealEnd { get; set; }
    public int OrderItemPartsCount { get; set; }
    public string CalculatedSeconds { get; set; }
    public string IdleSeconds { get; set; }
    public int ScheduledSeconds { get; set; }
    public int RealSeconds { get; set; }
    public int PercentComplete { get; set; }
    public bool HasFinishedItems { get; set; }
    public bool IsCustomTask { get; set; }
    public string AppointmentType { get; set; }
    public Station Station { get; set; }
    public MasterTask MasterTask { get; set; }
}

public class Station
{
    public string _Value { get; set; }
    public string oid { get; set; }
}

public class MasterTask
{
    public string _Value { get; set; }
    public string oid { get; set; }
}

反序列化代码

使用Newtonsoft.Json(Json.NET)

string responseJson = "API返回的JSON字符串";
var apiResponse = JsonConvert.DeserializeObject<ApiResponse>(responseJson);
List<TaskItem> tasks = apiResponse.Data.Order.Tasks;

使用System.Text.Json(.NET Core/.NET 5+内置)

string responseJson = "API返回的JSON字符串";
var apiResponse = JsonSerializer.Deserialize<ApiResponse>(responseJson);
List<TaskItem> tasks = apiResponse.Data.Order.Tasks;

方法2:动态解析(无需定义实体类)

如果只是临时提取数据,不想定义大量实体类,可以用动态类型直接定位Tasks:

使用Newtonsoft.Json的JObject

string responseJson = "API返回的JSON字符串";
var jObj = JObject.Parse(responseJson);
// 直接提取Tasks列表
List<JObject> tasks = jObj["Data"]["Order"]["Tasks"].ToObject<List<JObject>>();

使用System.Text.Json的JsonDocument

string responseJson = "API返回的JSON字符串";
using var doc = JsonDocument.Parse(responseJson);
var tasksElement = doc.RootElement.GetProperty("Data").GetProperty("Order").GetProperty("Tasks");
// 转成列表或按需遍历提取属性
List<JsonElement> tasks = tasksElement.EnumerateArray().ToList();

核心修改点

对比旧代码,原来的Data节点直接包含Tasks,现在需要多走一层Order节点——也就是从Data.Tasks改成Data.Order.Tasks,这是让代码恢复正常的关键。

内容的提问来源于stack exchange,提问作者Buda56

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 20:23:11