1

I have the following structure in my json file

  "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": ""
        }
    }
],

for this I have the following class

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

the uplinkPage section can have one or many of each of the EXE, RPC, VM .. sections. I have tried to add multiply sections like this

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

when I do the deserialization as so

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

I get an object and I can read everything except if I have multiply values of the same type, I will only get one of them. If I declare sections as array

public EXE[] exeList { get; set; }

I will get the last one and if as

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

I will get the first one. I have noticed that when I use the dictionary the type of the EXE changes to EXE1.

So I was wondering what am I doing wrong? am I mission some thing here?

cheers, es

2
  • Do you have control over the format of your JSON? Commented Feb 10, 2016 at 15:29
  • 1
    yes I have full control over it, but I think the one I am using is not correct. Commented Feb 10, 2016 at 15:37

1 Answer 1

1

Whenever you have a JSON property that might be duplicated, it will be easiest to represent the value of that property as JSON array, rather than multiple properties with duplicated names. I.e. instead of

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

You want to do:

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

Similarly, in the VM class, name appears multiple times, so name should be an array as well:

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

(It's not impossible to deserialize duplicated property names, just difficult, and requires a custom converter. See How to deserialize JSON with duplicate property names in the same object. Since you control your JSON format, I'd recommend avoiding this. Using a nested object with indexed properties as you propose in your question is also an option; it is less difficult but still requires custom conversion. See How to parse this JSON using Newton Soft for nested object. But using a JSON array is easiest.)

Next, you need to tell Json.NET how to map c# property names to JSON property names when they are inconsistent. For instance, in your JSON you have a property "EXE" but in c# the property name is public EXE[] exeList { get; set; }. You can either rename the JSON properties, rename the c# properties, or make the mapping using [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; }
}

I notice also that your EXE object sometimes has a "data-prog" property, and sometimes just a "prog". You should standardize on one.

Thus your JSON should look like:

{
  "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": ""
        }
      ]
    }
  ]
}

And your classes should look like:

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

prototype fiddle.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.