【问题标题】:Deserialize json arrays with newtonsoft使用 newtonsoft 反序列化 json 数组
【发布时间】:2015-12-11 11:02:33
【问题描述】:

如何使用 newtonsoft 反序列化 json 数组?

这是我的 json 文件:

{
    "one": [
      {
        "one":"1",
        "two":"2", 
        "three":"3"
      },
      {
        "one":"1",
        "two":"2", 
        "three":"3"
      }
    ],
    "two": [
      {
        "one":"1",
        "two":"2", 
        "three":"3"
      }
    ]
}

这是我的代码:

myList= JsonConvert.DeserializeObject <List<MyClass>>(jsonFile);

public class MyClass
{
    public string one{ get; set; }
    public string two { get; set; }
    public string three { get; set; }
}

也许我需要以某种方式更改我的 json 文件?

【问题讨论】:

  • 在 Visual Studio 的“特殊粘贴”菜单下有一个奇特的功能,可以将剪贴板中的 Json 粘贴到 C# 文件中,它会构造所有需要遵守的 C# 类说Json结构
  • 如果你有这么简单的json,就用这个网站json2csharp.com

标签: c# .net json json.net


【解决方案1】:

您的类需要与 JSON 的结构相匹配。它应该是这样的:

public class Foo
{
    [JsonProperty("one")]
    public string One { get; set; }
    [JsonProperty("two")]
    public string Two { get; set; }
    [JsonProperty("three")]
    public string Three { get; set; }
}

public class RootObject
{
    [JsonProperty("one")]
    public List<Foo> One { get; set; }
    [JsonProperty("two")]
    public List<Foo> Two { get; set; }
}

现在它会正确反序列化:

Console.WriteLine(JsonConvert.DeserializeObject<RootObject>(json));

【讨论】:

  • 如果 JSON 添加一个“第四”键怎么办?那么他是否需要添加一个 Forth 属性?这是错误的。只需将其反序列化为 Dictionary.
  • @JOSEFtw 如果 OP 声明:“我想在不修改 JSON 的情况下动态添加键”,那么字典可能更合适。由于 OP 只是想将 JSON 反序列化为正确的结构(并且“一”、“二”、“三”可能不是他的键),这应该可以完成工作。
  • 当然,但是如果你有相同的 JSON,你会像你回答的那样做还是用字典呢?我真的希望你回答“用字典”...
  • @JOSEFtw 同样,如果我需要动态解析编译时未知的键值对,明智的方法是使用字典甚至解析JObject。我认为这里不是这种情况,因为 OP 没有这么说。
【解决方案2】:

试试这个:

`public class Foo
{
    [JsonProperty("one")]
    public string One { get; set; }
    [JsonProperty("two")]
    public string Two { get; set; }
    [JsonProperty("three")]
    public string Three { get; set; }
}
public class RootObject
{
    [JsonProperty("one")]
    public List<Foo> One { get; set; }
    [JsonProperty("two")]
    public List<Foo> Two { get; set; }
}`

反序列化对象使用

` RootObject _rootObject = JsonConvert.DeserializeObject<RootObject>
  (jObject.ToString());`

【讨论】:

    【解决方案3】:

    如果你想保持你的类结构,你必须把你的 json 文件改成这样:

    [
       {
          "one":"1",
          "two":"2",
          "three":"3"
       },
       {
          "one":"1",
          "two":"2",
          "three":"3"
       }
    ]
    

    用这个json文件样式反序列化

    myList= JsonConvert.DeserializeObject <List<MyClass>>(jsonFile);
    

    将正确完成。

    您上面的 json 文件中有两个数组。因此反序列化会失败。

    【讨论】:

      【解决方案4】:

      那不是 JSON 数组,它是一个有两个数组属性的对象。

      使用http://json2csharp.com:

      public class YourClass
      {
          public string one { get; set; }
          public string two { get; set; }
          public string three { get; set; }
      }
      
      public class RootObject
      {
          public List<YourClass> one { get; set; }
          public List<YourClass> two { get; set; }
      }
      

      (难道我们还有对此有一个规范的问题吗?每天都一样......)

      【讨论】:

      • 为什么要添加所有这些类?为什么不直接将其反序列化为 Dictionary&lt;string, MyClass[]&gt;
      • @JOSEFtw 这有什么好处?当然,OneTwo 类可以是一个(您的 MyClass),而 RootObject 可以包含两个 List&lt;MyClass&gt;。我更赞成编译时类型安全(无需进行字符串匹配)。
      • 好处?它是动态的,如果 JSON 更新,您不需要添加新的 Class ForthClass Fifth....
      • @JOSEFtw “动态”是一个流行词。您提到的问题已通过我的更新解决。如果 JSON 发生更改,则无论如何您都需要更改代码。然后我宁愿重新生成类并出现编译时错误,也不愿忘记更改字符串并获得运行时错误。
      • 哈哈没有?如果他在他的 JSON 中添加了一个 "forth" : [],那么如果你使用字典,你就不需要更改代码?查看我的答案并自己尝试。
      【解决方案5】:

      您应该将其反序列化为Dictionary&lt;string, MyClass[]&gt;

      var test = "{ \"one\": [ { \"one\":\"1\", \"two\":\"2\", \"three\":\"3\" }, { \"one\":\"1\", \"two\":\"2\", \"three\":\"3\" } ], \"two\": [ { \"one\":\"1\", \"two\":\"2\", \"three\":\"3\" } ] }";
      var testar = JsonConvert.DeserializeObject <Dictionary<string, MyClass[]>>(test);
      

      如果添加更多键,如 Forth、Fifth 等,这将是开箱即用的。

      【讨论】:

      • 如果动态 json 中的实际变化是MyClass,而不是字典键,会发生什么?为什么不竭尽全力使用Dictionary&lt;string, List&lt;KeyValuePair&lt;string, string&gt;&gt;。让这个超级通用。
      • 我觉得很有趣,你对我的答案投了反对票,它有一个适当的(非动态)结构,但你的答案只提供了一种半动态的方法,你甚至不知道 OP 是否真的需要任何这个。
      • 它以硬编码的方式“正确”。但是我不会和你争论,如果你认为在 JSON 获取更新时添加一个 Forth、Fifth 和 Sixth 类是好的,那就继续吧:)
      • 如果MyClass 的任何属性更新,而不是外部键值,则必须修改您提供的解决方案。
      • 您的“推理”中有许多隐藏的假设,其中 OP 完全没有声明。但这仍然是一种不同的、合适的方法。不要仅仅因为你认为它更好而试图强迫“一种方法解决方案”。我会看到它实际上是首先需要的。
      猜你喜欢
      • 1970-01-01
      • 2021-10-13
      • 2017-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      相关资源
      最近更新 更多