0

Using C#, what is the correct way to deserialize a dynamic JSON object (ie: some JSON where the type of a single key can change between objects)?

For example, if I have this (perfectly valid) JSON:

{
  "stuffs": [
    { "content": "abcd" },
    { "content": "efgh" },
    { "content": [
        "ijkl",
        "mnop"
    ]}
  ]
}

where thing can be either a string or an array of strings, how do I deserialize this if I have these classes defined?

class ThingContainer {
  List<Thing> stuffs;
}

class Thing {
  List<string> content;
}

Attempting to deserialize I (expectedly) run into an exception:

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[DummyProject.Thing]'

Alex McMillan
  • 17,096
  • 12
  • 55
  • 88
  • 1
    http://stackoverflow.com/questions/18994685/how-to-handle-both-a-single-item-and-an-array-for-the-same-property-using-json-n this post will help you in designing the solution. – tRuEsAtM Apr 03 '17 at 22:24
  • @Sameer thanks, I don't know how I didn't find that when searching for existing questions. I think I've made a duplicate. – Alex McMillan Apr 03 '17 at 23:02

3 Answers3

0

Your issue is that your C# classes do not accurately represent the JSON.

Your JSON has an object which contains an object "stuffs" that is a list of objects "content" is a list of strings.

What you have in your C# classes is an object which contains an object that is a list of strings.

You need an object that contains an object that is a list of objects that contain a list of strings.

Try this:

public class Content
{
    public List<string> Content { get; set; }
}

public class Stuff
{
    public List<Content> Contents { get; set; }
}

public class ThingContainer
{
    public List<Stuff> Stuffs { get; set; }
}
Stephen P.
  • 2,221
  • 2
  • 15
  • 16
  • This wouldnt work for the last criteria/entry in the sample array, perhaps a custom formatter/deserializer that would deserialize to an list even if it is one item in a flat structure? – Chris Watts Apr 03 '17 at 22:02
  • 1
    I noticed that last requirement of it being a list and updated my response. – Stephen P. Apr 03 '17 at 22:13
0

I dont know if there any solution in C#, but i recomended you to adapte your JSON structure like:

{
  arrayStuffs[
    { content: ['123', '456'] },
    // another arrays...
  ],
  stringStuffs{
    content: '',
    // another strings..
  },
  // another stuffs, and so on
}

and define a models for all your stuffs:

public class arrayStuff{
  List<string> content;
}
0

I am not sure if this can be done with NewtonSoft, but if you go back to built-in APIs in Windows.Data.Json you can gain any flexibility that you want.

Ivan Ičin
  • 9,672
  • 5
  • 36
  • 57