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

C#反序列化嵌套JSON 合并多模型数据至单个CollectionView

问题根因
  • 一是实体类定义存在错误:Queryresult类中嵌套的客户属性定义成了Customer1类型,和实际嵌套的Customer2结构不匹配,反序列化时这层数据无法被正确填充
  • 二是反序列化代码存在大小写错误:C#是大小写敏感语言,定义的根类名是Root,反序列化时写的小写root会导致编译失败
  • 三是直接使用原始嵌套结构的Customer1集合作为绑定源,没有做多层数据的扁平化处理,无法拿到深层的Customer2、Lastpayment数据
实现步骤

1. 修正实体定义

首先修正Queryresult类的属性错误,对齐接口返回结构:

public class Queryresult
{
    public string responseMessage { get; set; }
    // 原代码此处错误定义为Customer1类型,修正为Customer2,属性名和接口返回字段保持一致
    public Customer2 customer2 { get; set; }
    public int responseCode { get; set; }
    public string status { get; set; }
}

如果接口返回的字段名和C#属性名不一致,可以用JsonProperty特性做映射,避免反序列化失败。

2. 定义统一绑定用的扁平化模型

创建专门用于UI绑定的模型类,把三个层级需要展示的字段全部平铺定义,不需要保留嵌套结构:

public class CustomerDisplayItem
{
    // Customer1 层级字段
    public string district { get; set; }
    public string feeder { get; set; }
    public string feeder_code { get; set; }
    public string transformer { get; set; }
    public string dss_code { get; set; }
    public string database_match { get; set; }
    public string accountnumber { get; set; }
    public string meterno { get; set; }

    // Customer2 层级字段
    public string phoneNumber { get; set; }
    public int billedAmount { get; set; }
    public object billedDate { get; set; }
    public string lastPayDate { get; set; }

    // Lastpayment 层级字段
    public string transactionRef { get; set; }
    public int units { get; set; }
    public string transactionDate { get; set; }
    public string transactionId { get; set; }
    public int transactionBookId { get; set; }
    public int amountPaid { get; set; }
    public int mscPaid { get; set; }
    public string invoiceNumber { get; set; }
}

3. 反序列化后投影展平数据

修正反序列化的类型名错误,通过LINQ访问各层嵌套数据,映射为统一的扁平化集合,过程中做空值容错避免空引用异常:

// 修正类名大小写错误,使用正确的Root类型反序列化
var data = JsonConvert.DeserializeObject<Root>(readTask);
if (data?.result?.Customer1 == null)
{
    // 处理接口返回空数据场景,绑定空集合即可
    yourCollectionView.ItemsSource = new ObservableCollection<CustomerDisplayItem>();
    return;
}

// 逐层访问嵌套数据,映射为统一的展示模型集合
var bindableCollection = new ObservableCollection<CustomerDisplayItem>(
    data.result.Customer1.Select(c1 => 
    {
        // 空值容错获取Customer2层数据
        Customer2 c2 = c1.transactional_details?.queryresult?.customer2;
        // 空值容错获取Lastpayment层数据
        Lastpayment lastPay = c2?.lastpayment;

        return new CustomerDisplayItem
        {
            // 映射Customer1字段
            district = c1.district,
            feeder = c1.feeder,
            feeder_code = c1.feeder_code,
            transformer = c1.transformer,
            dss_code = c1.dss_code,
            database_match = c1.database_match,
            accountnumber = c1.accountnumber,
            meterno = c1.meterno,

            // 映射Customer2字段,空值赋默认值
            phoneNumber = c2?.phoneNumber,
            billedAmount = c2?.billedAmount ?? 0,
            billedDate = c2?.billedDate,
            lastPayDate = c2?.lastPayDate,

            // 映射Lastpayment字段,空值赋默认值
            transactionRef = lastPay?.transactionRef,
            units = lastPay?.units ?? 0,
            transactionDate = lastPay?.transactionDate,
            transactionId = lastPay?.transactionId,
            transactionBookId = lastPay?.transactionBookId ?? 0,
            amountPaid = lastPay?.amountPaid ?? 0,
            mscPaid = lastPay?.mscPaid ?? 0,
            invoiceNumber = lastPay?.invoiceNumber
        };
    })
);

// 将最终展平的集合绑定到CollectionView
yourCollectionView.ItemsSource = bindableCollection;
注意事项
  • 所有嵌套层级访问都使用了null条件运算符?.,避免某一层数据缺失时抛出空引用异常
  • 值类型字段(比如int类型的金额、数量)空值时用??运算符赋值默认值0,避免绑定时报错
  • 如果后续需要修改集合,直接操作bindableCollection即可,它是ObservableCollection类型,会自动通知UI更新

内容的提问来源于stack exchange,提问作者GIS Support EEDC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:27:18