将JSON反序列化为List<T>时出错

5
我想将这个json反序列化为一个Product对象的List,但是我遇到了这个错误:
Newtonsoft.Json.JsonSerializationException: 无法将当前JSON对象(例如{"name":"value"})反序列化为类型'System.Collections.Generic.List`1[ShoppingList.Product]',因为该类型需要一个JSON数组(例如[1,2,3])才能正确反序列化。 要解决此错误,请将JSON更改为JSON数组(例如[1,2,3]),或更改反序列化类型,使其成为.NET普通类型(例如不是像整数这样的基元类型,也不是像数组或List这样的集合类型),可以从JSON对象反序列化。也可以向该类型添加JsonObjectAttribute,以强制它从JSON对象反序列化。
这是我的代码:
{
    "records": [
        {
            "id": "60",
            "name": "Rolex Watch",
            "description": "Luxury watch.",
            "price": "25000",
            "category_id": "1",
            "category_name": "Fashion"
        },
        {
            "id": "48",
            "name": "Bristol Shoes",
            "description": "Awesome shoes.",
            "price": "999",
            "category_id": "5",
            "category_name": "Movies"
        },
        {
            "id": "42",
            "name": "Nike Shoes for Men",
            "description": "Nike Shoes",
            "price": "12999",
            "category_id": "3",
            "category_name": "Motors"
        }
    ]   
}

public class Product
{
    public int id { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public decimal price { get; set; }
    public int category_id { get; set; }
    public string category_name { get; set; }
}

public async Task<List<Product>> GetProductsAsync()
    {
        Products = new List<Product>();

        var uri = new Uri("https://hostname/api/product/read.php");

        try
        {
            var response = await client.GetAsync(uri);
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
                Products = JsonConvert.DeserializeObject<List<Product>>(content);
            }
        }
        catch (Exception )
        {
            throw;
        }

        return Products;
    }
4个回答

11

您的Json不是List<Product>,而是一个只有一个名为records属性的对象,该属性是List<Product>类型。

因此,您实际上的C#模型应如下所示:

public class RootObject
{
    public List<Product> records { get; set; }
}

你可以像这样反序列化:

RootObject productsRoot = JsonConvert.DeserializeObject<RootObject>(content);

2
问题在于您提供的响应JSON是一个包含列表的对象,但您正在尝试将数据反序列化为直接列表。我认为您需要在代码中添加一个包含该列表的第二个类,然后使用该列表进行反序列化。
public class Product
{
    public int id { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public decimal price { get; set; }
    public int category_id { get; set; }
    public string category_name { get; set; }
}

public class RootProduct
{
    public List<Product> Products {get;set;}
}

那么您需要将反序列化部分从列表更改为:
RootProduct response = JsonConvert.DeserializeObject<RootProduct>(content);

使用方法很简单,只需调用products.response.Products即可访问项目列表。

0
问题出在你的 JSON 结构上。下面是一个 JSON 数组的示例 - 注意我删除了属性“records”。
[
    {
        "id": "60",
        "name": "Rolex Watch",
        "description": "Luxury watch.",
        "price": "25000",
        "category_id": "1",
        "category_name": "Fashion"
    },
    {
        "id": "48",
        "name": "Bristol Shoes",
        "description": "Awesome shoes.",
        "price": "999",
        "category_id": "5",
        "category_name": "Movies"
    },
    {
        "id": "42",
        "name": "Nike Shoes for Men",
        "description": "Nike Shoes",
        "price": "12999",
        "category_id": "3",
        "category_name": "Motors"
    }
]  

很好,你提出了构建更复杂对象的替代方案。当我正在写那部分内容时,你的帖子突然出现了 :) 我不想回答已经发布的问题,也不想删除我已经完成的工作,因为它并没有被你的帖子涉及到。 - Zakk Diaz

0

鉴于这些数据

[
    {
        "id": "60",
        "name": "Rolex Watch",
        "description": "Luxury watch.",
        "price": "25000",
        "category_id": "1",
        "category_name": "Fashion"
    },
    {
        "id": "48",
        "name": "Bristol Shoes",
        "description": "Awesome shoes.",
        "price": "999",
        "category_id": "5",
        "category_name": "Movies"
    },
    {
        "id": "42",
        "name": "Nike Shoes for Men",
        "description": "Nike Shoes",
        "price": "12999",
        "category_id": "3",
        "category_name": "Motors"
    }
]  

而这个类定义

public class Order
{
    public int id { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public string price { get; set; }
    public string category_id { get; set; }
    public string category_name { get; set; }
}

将其从JSON转换为C# List<Order>的代码如下:

public static List<Order> Map(string json)
{
    return Newtonsoft.Json.JsonConvert.DeserializeObject<List<Order>>(json);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接