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

C# Json.NET反序列化JSON为ObservableCollection类型报错

问题原因

异常已经明确给出根因:你调用的接口实际返回的是JSON对象(根节点存在type字段,对应异常提示的Path 'type', line 1, position 8),而非你预期的Video对象数组,因此无法直接反序列化为ObservableCollection<Video>类型。
这类问题绝大多数场景是后端接口做了统一响应包装,比如返回结构为{ "type": 业务状态, "data": 实际Video数组, "message": 提示信息 },而非直接返回数组;剩余场景为请求路径错误、接口报错,返回了错误信息对象。

排查步骤
  • 先获取接口真实返回值:在ReadAsStringAsync执行完成后加断点,或者直接打印result字符串到控制台,不要靠预设的返回结构写反序列化逻辑。
  • 校验请求合法性:先判断responseMessage.IsSuccessStatusCode是否为true,如果接口返回404、400、500等错误状态码,返回内容必然是错误对象,不可能是你要的数组。
  • 检查URL拼接逻辑:确认Base_url和qr参数拼接后地址正确,没有缺路径段、多斜杠、参数格式错误的问题,避免请求到错误的接口。
修复方案

1. 修复服务层请求逻辑

首先给请求加状态码校验,再根据实际返回结构调整反序列化代码。如果接口返回的是统一包装结构,先定义对应的通用响应类:

public class ApiResponse<T>
{
    // 对应异常提示里的type字段
    public string Type { get; set; }
    // 存放实际业务数据的字段,字段名要和接口返回的key完全一致,如果接口返回的key是data就写Data,是result就改对应名
    public T Data { get; set; }
    public string Message { get; set; }
}

修改search方法代码:

public async Task<ObservableCollection<Video>> search(string qr)
{
    string url = Base_url + "machines/" + qr;
    try
    {
        // 注意:HttpClient建议全局单例复用,不要每次请求new一个,频繁创建会导致socket耗尽,这里仅保留你原有逻辑做修改
        HttpClient client = new HttpClient();
        HttpResponseMessage responseMessage = await client.GetAsync(url);
        
        // 先判断响应状态
        if (!responseMessage.IsSuccessStatusCode)
        {
            string errorContent = await responseMessage.Content.ReadAsStringAsync();
            Console.WriteLine($"请求失败,状态码:{responseMessage.StatusCode},错误内容:{errorContent}");
            return null;
        }
        
        string result = await responseMessage.Content.ReadAsStringAsync();
        // 打印实际返回内容方便调试
        Console.WriteLine($"接口返回原文:{result}");
        
        // 反序列化为包装对象后取实际数据
        var apiResult = JsonConvert.DeserializeObject<ApiResponse<ObservableCollection<Video>>>(result);
        return apiResult?.Data;
        
        // 如果排查后确认接口直接返回数组,把上面两行替换为以下代码即可
        // var videoList = JsonConvert.DeserializeObject<ObservableCollection<Video>>(result);
        // return videoList;
    }
    catch(Exception ex)
    {
        Console.WriteLine($"请求异常:{ex.Message}\n堆栈:{ex.StackTrace}");
    }
    return null;
}

2. 修复View层绑定问题

你当前的Videos属性赋值后没有触发属性变更通知,ListView无法感知数据更新,需要补全PropertyChanged触发逻辑:

public ObservableCollection<Video> Videos
{
    get { return videos; }
    set
    {
        videos = value;
        // 触发属性变更通知,你的INotifyPropertyChanged接口实现里应该已经有OnPropertyChanged方法,直接调用即可
        OnPropertyChanged(nameof(Videos));
    }
}

3. 字段匹配问题

如果后续反序列化出现部分字段为null的情况,是因为C#属性名和JSON字段名不匹配,可以给对应属性加[JsonProperty("JSON字段名")]特性映射,比如:

public class Video
{
    [Key]
    [JsonProperty("videoId")]
    public int VideoId { get; set; }
    [JsonProperty("exercice")]
    public string Exercice { get; set; }
    // 其余字段按相同方式加映射即可
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:06:07