使用顶级数组和第一个未命名对象反序列化 Json

Deserialize Json with top Array and first unnamed object

我正在消费 API returns 以下 JSON:

[
    {
        "product": {
            "id": 2,
            "name": "Auto"
        }
    }
]

所以,我试图在 C# 对象中反序列化它,但没有成功。

我尝试了很多其他的 Whosebug 解决方案。

这是我的尝试:

public class DomainMessageResponse : BaseResponseMessage
{
    public Example data { get; set; }
}

public class Example
{
    [JsonProperty("product")]
    public Product product { get; set; }
}

public class Product
{
    [JsonProperty("id")]
    public int id { get; set; }

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

问题是 JSON 以 [] 开头,而我们的通用方法(我从内部框架中使用)无法使用它。我收到以下异常:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type....

感谢@EZI 和@eocron 提供有效的解决方案。

您应该反序列化为 array/list。下面的代码应该可以工作...

var list = JsonConvert.DeserializeObject<List<Item>>(json);

public class Product
{
    public int id { get; set; }
    public string name { get; set; }
}

public class Item
{
    public Product product { get; set; }
}

考虑到您要使用对象的方式,您的问题有两种解决方案。

第一个是简单地创建具有相同字段的 DTO。当您需要完全控制时使用:

using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace ConsoleTest
{
    class Program
    {
        [DataContract]
        public class Example
        {
            [DataMember]
            public Product Product { get; set; }
        }

        [DataContract]
        public class Product
        {
            [DataMember]
            public int Id { get; set; }
            [DataMember]
            public string Name { get; set; }
        }

        static void Main(string[] args)
        {
            var json = @"
                            [
                                {
                                    ""product"": {
                                        ""id"": 2,
                                        ""name"": ""Auto""
                                    }
                                }
                            ]";

            var obj = JsonConvert.DeserializeObject<List<Example>>(json,
                                                         new JsonSerializerSettings
                                                         {
                                                             ContractResolver = new CamelCasePropertyNamesContractResolver()
                                                         });
        }
    }
}

当您想要 json 中的几个字段并且不太关心其他所有内容时使用第二个,并使用 dynamic 类型。易于编码,易于使用,看起来不错,但不太安全:

using System.Collections.Generic;
using Newtonsoft.Json;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var json = @"
                            [
                                {
                                    ""product"": {
                                        ""id"": 2,
                                        ""name"": ""Auto""
                                    }
                                }
                            ]";

            dynamic list = JsonConvert.DeserializeObject<List<dynamic>>(json);
            var id = (int)list[0].product.id;
        }
    }
}