【问题标题】:Deserialize json array to c# list object将json数组反序列化为c#列表对象
【发布时间】:2018-05-15 05:40:38
【问题描述】:

我正在尝试解析从服务到 c# 观察集合列表对象的 JSON 响应。列表对象稍后可用于在 XAML 页面上展示。

这是来自服务的响应:

[
  {
    "orderId": 1,
    "employeeId": "6364",
    "orderTime": 1517583600000,
    "orderCost": 90,
    "comments": null,
    "orderStatus": {
      "orderStatusId": 1,
      "orderStatusName": "Order Placed"
    },
    "orderedItems": [
      {
        "orderItemId": 1,
        "orderQuantity": 1,
        "orderItemCost": 50
      },
      {
        "orderItemId": 2,
        "orderQuantity": 1,
        "orderItemCost": 40
      }
    ]
  },
  {
    "orderId": 2,
    "employeeId": "6364",
    "orderTime": 1517670000000,
    "orderCost": 50,
    "comments": null,
    "orderStatus": {
      "orderStatusId": 3,
      "orderStatusName": "Order Delivered"
    },
    "orderedItems": [
      {
        "orderItemId": 3,
        "orderQuantity": 1,
        "orderItemCost": 50
      }
    ]
  }
]

以下是模型类:

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; }

        [JsonProperty("orderTime")]
        public object orderTime { get; set; }
        [JsonProperty("orderCost")]
        public int orderCost { get; set; }

        [JsonProperty("comments")]
        public object comments { get; set; }

        [JsonProperty("orderStatus")]
        public OrderStatus orderStatus { get; set; }

        [JsonProperty("orderedItems")]
        public List<OrderedItem> orderedItems { get; set; }
    }


}

服务是这样的:

public  class OrderService
    {
        public OrderService()
        {
            GetJson();
        }
        public async void GetJson()
        {
            if (NetworkCheck.IsInternet())
            {
                var client = new System.Net.Http.HttpClient();
                var response = await client.GetAsync("here is thre URL");
                string orderJson = await response.Content.ReadAsStringAsync(); //Getting response  

                Order ObjOrderList = new Order();
                if (orderJson != " ")
                {

                    Console.WriteLine("response is"+orderJson);

                   //exception occurs here all the time , and I need it to be a list
                    ObjOrderList = JsonConvert.DeserializeObject<Order>(orderJson);
                }

                Console.WriteLine("obj order list is"+ObjOrderList);
            }
        }
    }

在尝试将 JSON 数组反序列化为 c# 进行一些更改后,我无法成功。现在有一个例外说

Newtonsoft.Json.JsonSerializationException: <Timeout exceeded getting exception details>

我被困了很长时间,在 StackOverflow 上搜索并用谷歌搜索,但没有有效的解决方案。

我需要将 JSON 数据存储到一个 c# 对象中,并在 XAML 页面中以列表的形式重现相同的对象。

提前致谢!

【问题讨论】:

  • 看看ex.InnerException有没有细节
  • innerException 什么都没有
  • async void 不用于事件处理程序时是代码味道,构造函数中的长期操作也是代码味道

标签: c# rest xaml xamarin.forms json.net


【解决方案1】:

我确定该异常与您的 JSON 字符串无关,但请尝试从解决方案文件夹中删除 binobj,然后清理并重建解决方案。

但是在解决之后你会得到下面的异常

无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“namespace.Order”,因为该类型需要 JSON 对象(例如 {"name":"value"})才能正确反序列化。 ...

因为您的 JSON 字符串是 Order 的列表,所以反序列化将更改为:

List<Order> ObjOrderList = JsonConvert.DeserializeObject<List<Order>>(orderJson);

或者在另一边你也可以使用JavaScriptSerializer like:

Order[] orderList = new JavaScriptSerializer().Deserialize<Order[]>(orderJson);

【讨论】:

  • 一点注意:您也可以将JsonConvert 用作JsonConvert.DeserializeObject&lt;Order[]&gt;(json);
【解决方案2】:

你正在反序列化一个订单列表,所以你应该像这样反序列化:

...
List<Order> ObjOrderList;
...
ObjOrderList = JsonConvert.DeserializeObject<List<Order>>(orderJson);
...

【讨论】:

  • 我已经更改了代码,但仍然存在相同的异常。
  • 您的服务代码是原始代码还是手动剥离的样本?
  • 实际上这对我有用...今天我已经更改了代码并且效果很好...非常感谢
【解决方案3】:

您的 JSON 以 [ 开头,以 ] 结尾。这意味着您的 JSON 代表一个对象数组。这些对象是:

第一个对象

{
    "orderId": 1,
    "employeeId": "6364",
    "orderTime": 1517583600000,
    "orderCost": 90,
    ...
}

第二个对象

{
    "orderId": 2,
    "employeeId": "6364",
    "orderTime": 1517670000000,
    "orderCost": 50,
    ...
}

在你的潜意识里你知道,事实上你的反序列化变量的名字是ObjOrderList(高亮List)。

所以,只需反序列化为 Order 的数组/列表。

列表示例

var ObjOrderList = new List<Order>();
if (orderJson != " ")
{
    //exception occurs here all the time , and I need it to be a list
    ObjOrderList = JsonConvert.DeserializeObject<List<Order>>(orderJson);
}

数组示例

var ObjOrderList = new Order[] { };
if (orderJson != " ")
{
    //exception occurs here all the time , and I need it to be a list
    ObjOrderList = JsonConvert.DeserializeObject<Order[]>(orderJson);
}

【讨论】:

  • 感谢回复,我已经相应地更改了代码,但是有 Newtonsoft.Json.JsonReaderException: 但我喜欢 SUBCONSCIOUS 这个词。
  • 我执行了我发布的代码,没有任何错误。尝试将您的 JSON 放入一个变量中,然后执行您的代码。我将 JSON 放在一个文件中,然后使用:string orderJson = File.ReadAllText(@"C:\file.txt"); 读取它。然后执行你的代码。这确保您的问题与输入无关。
  • 但是我使用的 json 不是来自变量,它来自服务,所以我无法从文本文件中获取 json
  • 是的,它只是为了调试。将您的示例 JSON(您在问题中发布的那个)放在一个文件中并保存。然后使用File.ReadAllText 获取文件内容。通过这种方式,您可以了解问题是来自请求的响应还是来自 JSON 本身(这不应该,因为它对我有用)。
【解决方案4】:

试试这个自动生成的代码:

// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using yourNameSpace;
//
//    var orderResponse = OrderResponse.FromJson(jsonString);

namespace yourNameSpace
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

public partial class OrderResponse
{
    [JsonProperty("orderId")]
    public long OrderId { get; set; }

    [JsonProperty("employeeId")]
    public string EmployeeId { get; set; }

    [JsonProperty("orderTime")]
    public long OrderTime { get; set; }

    [JsonProperty("orderCost")]
    public long OrderCost { get; set; }

    [JsonProperty("comments")]
    public object Comments { get; set; }

    [JsonProperty("orderStatus")]
    public OrderStatus OrderStatus { get; set; }

    [JsonProperty("orderedItems")]
    public List<OrderedItem> OrderedItems { get; set; }
}

public partial class OrderStatus
{
    [JsonProperty("orderStatusId")]
    public long OrderStatusId { get; set; }

    [JsonProperty("orderStatusName")]
    public string OrderStatusName { get; set; }
}

public partial class OrderedItem
{
    [JsonProperty("orderItemId")]
    public long OrderItemId { get; set; }

    [JsonProperty("orderQuantity")]
    public long OrderQuantity { get; set; }

    [JsonProperty("orderItemCost")]
    public long OrderItemCost { get; set; }
}

public partial class OrderResponse
{
    public static List<OrderResponse> FromJson(string json) => JsonConvert.DeserializeObject<List<OrderResponse>>(json);
}

代码是使用QuickType.io 生成的 我丢弃了转换器和其他一些额外的类。 您可以根据需要将 Long 类型更改为 int。

要使用它,只需调用

var orderResponse = OrderResponse.FromJson(jsonString);

传递响应而不是 jsonString

【讨论】:

    【解决方案5】:

    在这段代码中你可以DeserializeObjectjson 文件:

     using (StreamReader r = new StreamReader("D:/Source/ParsijooWeatherApi/ParsijooWeatherApi/cities2.json"))
            {
                string json = r.ReadToEnd();
                List<jsonVariables> items = JsonConvert.DeserializeObject<List<jsonVariables>>(json);
    
                dynamic array = JsonConvert.DeserializeObject(json);
                foreach (var item in array)
                {
                    Console.WriteLine("{0} {1}", item.latitude, item.longitude);
                }
            }
    

    jsonVariables 类是:

    public class jsonVariables
    {
        [JsonProperty("latitude")]
        public string latitude { get; set; }
    
        [JsonProperty("longitude")]
        public string longitude { get; set; }
    
        [JsonProperty("state")]
        public string state { get; set; }
    }
    

    在这段代码中你访问根目录项目:

     string _filePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);
    

    然后:

    StreamReader r = new StreamReader(_filePath + "/cities2.json"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 2022-12-13
      • 2013-02-10
      相关资源
      最近更新 更多