【问题标题】:Deserializing with a json file with inner classes with JSON.NET C#使用带有 JSON.NET C# 的内部类的 json 文件反序列化
【发布时间】:2016-02-11 00:22:07
【问题描述】:

我的 json 文件中有以下结构

  "missionName": "missionname",
  "thumb_image": "pics/mission-info.png",
   "uplinkPage": [
    {
        "RPC": {
            "name": "RPC",
            "rpc": "",
            "args": ""
        },
        "EXE": {
            "name": "app1",
            "prog": "",
            "args": ""
        },
        "VM": {
            "name": "VM",
            "name": "",
            "args": ""
        },
        "JAR": {
            "name": "JAR",
            "prog": "",
            "args": ""
        },
        "link": {
            "name": "somelink",
            "url": ""
        }
    }
],

为此,我有以下课程

 public class EXE
{
   public string name { get; set; }
   public string prog { get; set; }
   public string args { get; set; }
}

public class RPC
{
    public string name { get; set; }
    public string rpc { get; set; }
    public string args { get; set; }
}

public class VM
{
    public string name { get; set; }
    public string args { get; set; }
}

public class JAR
{
    public string name { get; set; }
    public string prog { get; set; }
    public string args { get; set; }
}

public class Link
{
    public string name { get; set; }
    public string url { get; set; }
}

 public class UplinkPage
{
    public VM[] vmList { get; set; }
    public EXE[] exeList { get; set; }
    public RPC[] rpcList { get; set; }
    public JAR[] jarList { get; set; }
    public Link[] linkList { get; set; }
}

 public class Rootobject
{
    public string missionName { get; set; }
    public string thumb_image { get; set; }     
    public Uplinkpage[] uplinkPage { get; set; }        
}

uplinkPage 部分可以有一个或多个 EXE、RPC、VM .. 部分。我试图添加这样的乘法部分

"EXE": {
            "1": {
                "name": "app1",
                "data-prog": "",
                "data-args": ""
            },
            "2": { 
                "name": "app2",
            "data-prog": "",
            "data-args": ""
            }
        }

当我这样进行反序列化时

Rootobject page = JsonConvert.DeserializeObject<Rootobject>(File.ReadAllText("mission1.json"));

我得到一个对象,我可以读取所有内容,除非我有多个相同类型的值,我只会得到其中一个。如果我将部分声明为数组

public EXE[] exeList { get; set; }

我会得到最后一个,如果是

Dictionary<string,EXE> exeList {get; set;}

我会得到第一个。我注意到,当我使用字典时,EXE 的类型变为 EXE1。

所以我想知道我做错了什么?我在这里有什么任务吗?

干杯, 是的

【问题讨论】:

  • 您可以控制 JSON 的格式吗?
  • 是的,我可以完全控制它,但我认为我使用的那个不正确。

标签: c#-4.0 json.net


【解决方案1】:

当您有一个可能重复的 JSON 属性时,最简单的方法是将该属性的值表示为 JSON array,而不是具有重复名称的多个属性。 IE。而不是

{
    "EXE" : {"id":1},
    "RPC" : {"name":"a"},        
    "EXE" : {"id":2},
}

你想做的:

{
    "EXE" : [{"id":1}, {"id":2}],
    "RPC" : [{"name":"a"}]        
}

同样,在VM 类中,name 出现多次,所以name 也应该是一个数组:

public class VM
{
    public string [] name { get; set; }
    public string args { get; set; }
}

(对重复的属性名称进行反序列化并非不可能,只是很困难,并且需要自定义转换器。请参阅How to deserialize JSON with duplicate property names in the same object。由于您可以控制 JSON 格式,因此我建议您避免这种情况。使用您在问题中提出的具有索引属性的嵌套对象也是一种选择;它不那么困难,但仍需要自定义转换。请参阅How to parse this JSON using Newton Soft for nested object。但使用 JSON 数组是最简单的。)

接下来,你需要告诉 Json.NET 在 c# 属性名不一致时如何将它们映射到 JSON 属性名。例如,在您的 JSON 中,您有一个属性 "EXE",但在 c# 中,属性名称是 public EXE[] exeList { get; set; }。您可以重命名 JSON 属性、重命名 c# 属性或使用 [JsonProperty] 进行映射:

public class UplinkPage
{
    [JsonProperty("VM")]
    public VM[] vmList { get; set; }

    [JsonProperty("EXE")]
    public EXE[] exeList { get; set; }

    [JsonProperty("RPC")]
    public RPC[] rpcList { get; set; }

    [JsonProperty("JAR")]
    public JAR[] jarList { get; set; }

    [JsonProperty("link")]
    public Link[] linkList { get; set; }
}

我还注意到您的EXE 对象有时具有"data-prog" 属性,有时只有"prog"。你应该标准化一个。

因此您的 JSON 应该如下所示:

{
  "missionName": "missionname",
  "thumb_image": "pics/mission-info.png",
  "uplinkPage": [
    {
      "RPC": [
        {
          "name": "RPC",
          "rpc": "",
          "args": ""
        }
      ],
      "EXE": [
        {
          "name": "app1",
          "prog": "prog1",
          "args": "args1"
        },
        {
          "name": "app2",
          "prog": "prog2",
          "args": "args2"
        }
      ],
      "VM": [
        {
          "name": [
            "VM",
            ""
          ],
          "args": ""
        }
      ],
      "JAR": [
        {
          "name": "JAR",
          "prog": "",
          "args": ""
        }
      ],
      "link": [
        {
          "name": "somelink",
          "url": ""
        }
      ]
    }
  ]
}

你的课程应该是这样的:

public class EXE
{
    public string name { get; set; }
    public string prog { get; set; }
    public string args { get; set; }
}

public class RPC
{
    public string name { get; set; }
    public string rpc { get; set; }
    public string args { get; set; }
}

public class VM
{
    public string [] name { get; set; }
    public string args { get; set; }
}

public class JAR
{
    public string name { get; set; }
    public string prog { get; set; }
    public string args { get; set; }
}

public class Link
{
    public string name { get; set; }
    public string url { get; set; }
}

public class UplinkPage
{
    [JsonProperty("VM")]
    public VM[] vmList { get; set; }

    [JsonProperty("EXE")]
    public EXE[] exeList { get; set; }

    [JsonProperty("RPC")]
    public RPC[] rpcList { get; set; }

    [JsonProperty("JAR")]
    public JAR[] jarList { get; set; }

    [JsonProperty("link")]
    public Link[] linkList { get; set; }
}

public class Rootobject
{
    public string missionName { get; set; }
    public string thumb_image { get; set; }
    public UplinkPage[] uplinkPage { get; set; }
}

原型fiddle.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多