【问题标题】:Deserialize JSON Object into Class将 JSON 对象反序列化为类
【发布时间】:2016-02-11 18:55:21
【问题描述】:

我在将 JSON 对象反序列化为类(使用 JSON.NET)时遇到了一点麻烦,希望有人能指出我正确的方向。下面是我正在尝试的一段代码,并在dotnetfiddle进行测试

这是 JSON 的示例:

{
    "`LCA0001": {
        "23225007190002": "1",
        "23249206670003": "1",
        "01365100070018": "5"
    },
    "`LCA0003": {
        "23331406670018": "1",
        "24942506670004": "1"
    },
    "`LCA0005": {
        "01365100070018": "19"
    }
}

我正在尝试使用此代码:

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

public class Program
{
    public static void Main()
    {

        string json = "{\"`LCA0001\": {\"23225007190002\": \"1\",\"23249206670003\": \"1\",\"01365100070018\": \"5\"},\"`LCA0003\": {\"23331406670018\": \"1\",\"24942506670004\": \"1\"},\"`LCA0005\": {\"01365100070018\": \"19\"}}";
        Console.WriteLine(json);
        Console.WriteLine();

        //This works
        Console.Write("Deserialize without class");
        var root = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, int>>>(json);
        foreach (var locationKvp in root)
        {
            foreach (var skuKvp in locationKvp.Value)
            {
                Console.WriteLine("location: " + locationKvp.Key + ", sku: " +  skuKvp.Key + ", qty: " + skuKvp.Value);
            }
        }

        //Why doesn't this work?
        Console.Write("\nDeserialize with class");      
        var root2 = JsonConvert.DeserializeObject<InventoryLocations>(json);
        foreach (var locationKvp in root2.InventoryLocation)
        {
            foreach (var skuKvp in locationKvp.Value)
            {
                Console.WriteLine("location: " + locationKvp.Key + ", sku: " +  skuKvp.Key + ", qty: " + skuKvp.Value);
            }
        }
    }
}

class InventoryLocations
{
    public Dictionary<Location, Dictionary<Sku, Qty>> InventoryLocation { get; set; }
}

public class Location
{
    public string location { get; set; }
}

public class Sku
{
    public string sku { get; set; }
}

public class Qty
{
    public int qty { get; set; }
}

反序列化为 Class 不起作用有什么原因吗?我只是错误地定义了类吗?

【问题讨论】:

  • 你的因为它们反序列化不一样? (Dictionary&lt;string, Dictionary&lt;string, int&gt;&gt;&gt; 与用类代替字符串(您的 JSON 与该字符串不匹配)。
  • 看起来您的第二个示例(不起作用的示例)嵌套更深一层。在您的第一个示例中,如果您反序列化为 Dictionary> 而不是 Dictionary> 会起作用吗?

标签: c# json.net json-deserialization


【解决方案1】:

我在这里看到两个问题:一个是使用类作为字典键 - JSON 在那里有简单的字符串(实际上不能有其他任何东西),所以这不起作用。

第二个问题是 JSON 到类的反序列化是通过将键与属性匹配来实现的 - 所以它会转换类似的东西

{
    "prop1": "value1",
    "prop2": "value2"
}

到一个实例:

public class MyClass {
   public string prop1 { get; set; }
   public string prop2 { get; set; }
}

在您的情况下,这不起作用,因为在您的 JSON 中,所有键都不是有效的属性名称。你必须坚持反序列化到字典

【讨论】:

  • 啊,那是我不明白的。感谢您的澄清。
【解决方案2】:

从 JSON 生成类的方法之一是使用 Visual Studio。

导航到Edit -&gt; Paste Special -&gt; Paste JSON As Classes。对于发布的相关 JSON,会生成以下类。

public class Rootobject
{
    public LCA0001 LCA0001 { get; set; }
    public LCA0003 LCA0003 { get; set; }
    public LCA0005 LCA0005 { get; set; }
}

public class LCA0001
{
    public string _23225007190002 { get; set; }
    public string _23249206670003 { get; set; }
    public string _01365100070018 { get; set; }
}

public class LCA0003
{
    public string _23331406670018 { get; set; }
    public string _24942506670004 { get; set; }
}

public class LCA0005
{
    public string _01365100070018 { get; set; }
}

【讨论】:

  • 上一页...展示如何通过将 JSON 粘贴为类来提高生产力。
  • 附带说明:将 JSON 粘贴为类仅在您编辑代码文件时可见。看到这个答案:stackoverflow.com/a/18527793/642579
  • 虽然粘贴为类很棒,但它似乎对这个问题没有任何价值,因为“名称”似乎是可变的,而不是固定的类名称和属性。
  • 感谢您的提示。平时都用过json2charp.com这样的在线工具,没想到在VS里也可以直接搞定。
【解决方案3】:

除了 MiMo 的回答之外,您还可以使用 ContractResolver 来序列化/反序列化类中的字典。

Here's a working example of your code in dotnetfiddle.

请注意,带有合约解析器的序列化 Json 与原始 json 不同。必须使用此合约解析器对其进行序列化,才能对其进行反序列化。

如果您需要更多说明,我从this StackOverflow question 提取了合同解析器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    相关资源
    最近更新 更多