【问题标题】:Deserialize Json with top Array and first unnamed object使用顶部数组和第一个未命名对象反序列化 Json
【发布时间】:2017-08-10 18:23:32
【问题描述】:

我正在使用一个返回以下 JSON 的 API:

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

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

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

这是我的尝试:

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 以 [] 开头,而我们的通用方法(我从内部框架中使用)无法使用它。我收到以下异常:

无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型......

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

【问题讨论】:

  • 你试过什么?你知道json2csharp.com吗?你使用 Json.Net 吗?
  • 哦,真的吗?您能与我们分享这些解决方案,以便我们了解更多问题。
  • 这看起来不像是一个有效的 JSON ... 不确定您是指 JSON 数组还是什么?
  • @Rahul jsonlint.com 说它是有效的 json
  • @SirRufo,在语法上是的,但这样他最终可能会完全使用不同的模型......可能是

标签: c# json json-deserialization


【解决方案1】:

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

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

【讨论】:

  • 我的猜测 .. OP 可能意味着 Product[] 而不是
  • 不错。但是,在我的公司中,我们正在使用 SOA,并且我们有一些框架,其中一个是从外部 API 获取,我发现我们的方法不准备使用这种类型的 JSON(以数组开头)。所以,我非常感谢你的回答。它是有效的并且工作得很好。我会用一些 Json 来测试它。
【解决方案2】:

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

第一个是简单地创建具有相同字段的 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中的几个字段并且不太关心其他所有内容时使用第二个,并使用动态类型。易于编码,易于使用,看起来还不错,但不是很安全:

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

【讨论】:

  • 非常感谢 eocron。您的解决方案效果很好。我已经要求我们的架构师实施一个以 [ ] 开头的 JSON 到期的解决方案。
猜你喜欢
  • 1970-01-01
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 2013-08-14
  • 2017-07-31
相关资源
最近更新 更多