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

如何将JSON数组反序列化为C# List对象并在XAML页面展示

解决JSON反序列化异常并在XAML展示订单列表

咱们先揪出你遇到的核心问题:服务返回的JSON是一个Order对象的数组,但你在反序列化的时候却试图转换成单个Order实例,这直接导致了Newtonsoft.Json的序列化异常。除此之外还有几个小问题需要调整,咱们一步步来修复:

1. 修正反序列化的目标类型

你的JSON结构是[{}, {}](数组格式),所以反序列化时要指定List<Order>类型,而不是单个Order。这是引发异常的最关键原因。

2. 调整Order模型的字段类型

  • orderTime在JSON里是毫秒级时间戳(数字格式),你现在用object类型太宽泛,建议改成long存储,或者直接转换成DateTime(需要加JSON转换器):
    // 方案1:用long存储时间戳,后续再转成可读DateTime
    [JsonProperty("orderTime")]
    public long orderTime { get; set; }
    
    // 方案2:直接转DateTime,需引入Newtonsoft.Json的转换器
    [JsonProperty("orderTime")]
    [JsonConverter(typeof(UnixDateTimeConverter))]
    public DateTime orderTime { get; set; }
    
  • comments字段如果是字符串类型(可能为null),可以改成string而不是object,更贴合实际业务场景。

3. 修复异步方法的问题

async void仅适合事件处理方法,普通异步方法应该用async Task,否则可能导致异步操作无法正确等待、异常无法捕获等隐性问题。

4. 修正空字符串判断逻辑

原来的if (orderJson != " ")完全不符合预期,应该用!string.IsNullOrWhiteSpace(orderJson)来判断响应内容是否有效。


修正后的完整代码

调整后的模型类

namespace ServiceNew
{
    public class OrderStatus
    {
        public int orderStatusId { get; set; }
        public string orderStatusName { get; set; }
    }

    public class OrderedItem
    {
        [JsonProperty("orderItemId")]
        public int orderItemId { get; set; }
        [JsonProperty("orderQuantity")]
        public int orderQuantity { get; set; }
        [JsonProperty("orderItemCost")]
        public int orderItemCost { get; set; }
    }

    public class Order
    {
        [JsonProperty("orderId")]
        public int orderId { get; set; }
        [JsonProperty("employeeId")]
        public string employeeId { get; set; }
        // 用long存储时间戳,新增计算属性转成可读DateTime
        [JsonProperty("orderTime")]
        public long orderTime { get; set; }
        [JsonProperty("orderCost")]
        public int orderCost { get; set; }
        // 改成string类型更合理
        [JsonProperty("comments")]
        public string comments { get; set; }
        [JsonProperty("orderStatus")]
        public OrderStatus orderStatus { get; set; }
        [JsonProperty("orderedItems")]
        public List<OrderedItem> orderedItems { get; set; }

        // 可选:自动把时间戳转成可读格式
        public DateTime OrderTimeDisplay => DateTimeOffset.FromUnixTimeMilliseconds(orderTime).LocalDateTime;
    }
}

修正后的OrderService

public class OrderService
{
    // 把单个Order改成List<Order>存储结果
    public List<Order> ObjOrderList { get; set; }

    public OrderService()
    {
        // 注意:构造函数里不要直接调用异步方法,建议在外部通过await调用GetJson
        // _ = GetJson();
    }

    // 把async void改成async Task,保证异步逻辑可控
    public async Task GetJson()
    {
        if (NetworkCheck.IsInternet())
        {
            // 使用using自动释放HttpClient资源
            using var client = new System.Net.Http.HttpClient();
            var response = await client.GetAsync("your-api-url-here");
            // 确保请求成功再继续处理
            response.EnsureSuccessStatusCode();
            string orderJson = await response.Content.ReadAsStringAsync();

            if (!string.IsNullOrWhiteSpace(orderJson))
            {
                Console.WriteLine("response is: " + orderJson);
                // 反序列化成List<Order>
                ObjOrderList = JsonConvert.DeserializeObject<List<Order>>(orderJson);
                Console.WriteLine($"obj order list count: {ObjOrderList?.Count ?? 0}");
            }
        }
    }
}

在XAML页面展示订单列表

接下来咱们把订单列表绑定到XAML的ListView控件,实现数据展示:

1. 准备ViewModel(推荐使用)

建议用ViewModel管理数据,实现INotifyPropertyChanged以便数据更新时UI自动刷新:

public class OrdersViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Order> _orders;
    public ObservableCollection<Order> Orders
    {
        get => _orders;
        set
        {
            _orders = value;
            OnPropertyChanged();
        }
    }

    private readonly OrderService _orderService;

    public OrdersViewModel()
    {
        _orders = new ObservableCollection<Order>();
        _orderService = new OrderService();
        LoadOrders();
    }

    private async void LoadOrders()
    {
        await _orderService.GetJson();
        if (_orderService.ObjOrderList != null)
        {
            Orders.Clear();
            foreach (var order in _orderService.ObjOrderList)
            {
                Orders.Add(order);
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. XAML页面代码

<Page.DataContext>
    <local:OrdersViewModel />
</Page.DataContext>

<ListView ItemsSource="{Binding Orders}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin="10">
                <TextBlock Text="Order ID:" FontWeight="Bold"/>
                <TextBlock Text="{Binding orderId}" Margin="0 0 0 5"/>
                <TextBlock Text="Status:" FontWeight="Bold"/>
                <TextBlock Text="{Binding orderStatus.orderStatusName}" Margin="0 0 0 5"/>
                <TextBlock Text="Total Cost:" FontWeight="Bold"/>
                <TextBlock Text="{Binding orderCost, StringFormat='${0}'}" Margin="0 0 0 5"/>
                <TextBlock Text="Order Time:" FontWeight="Bold"/>
                <TextBlock Text="{Binding OrderTimeDisplay, StringFormat='{0:yyyy-MM-dd HH:mm}'}" Margin="0 0 0 10"/>
                
                <!-- 展示订单项详情 -->
                <TextBlock Text="Items:" FontWeight="Bold"/>
                <ItemsControl ItemsSource="{Binding orderedItems}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" Margin="5 0">
                                <TextBlock Text="Item ID: "/>
                                <TextBlock Text="{Binding orderItemId}"/>
                                <TextBlock Text=" | Qty: "/>
                                <TextBlock Text="{Binding orderQuantity}"/>
                                <TextBlock Text=" | Cost: $"/>
                                <TextBlock Text="{Binding orderItemCost}"/>
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
                <Border Height="1" Background="Gray" Margin="0 10"/>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

这样调整后,你应该能成功完成JSON反序列化,并在XAML页面正常展示订单列表了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:55:35