我的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"));
我得到一个对象,我可以读取所有内容,除非我有相同类型的乘法值,我只会得到其中一个。如果我将section声明为array
public EXE[] exeList { get; set; }
我会得到最后一个,如果是
Dictionary<string,EXE> exeList {get; set;}
我会得到第一个。我注意到当我使用字典时,EXE的类型变为EXE1。
所以我想知道我做错了什么?我在这里执行任务吗?
欢呼声, ES
答案 0 :(得分:1)
每当您拥有可能重复的JSON属性时,最简单的方法是将该属性的值表示为JSON array,而不是具有重复名称的多个属性。即而不是
{
"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。