0

I've just started to work with JSON and after having read a few articles, I'm still unclear if I'm looking at an array, list or just an object. It looks like this.

{
  "list": [{
    "fields": {
      "id": "9222115557374550596",
      ...
    },
  },
  {
    "fields": {
      "id": "9222115557374550597",
      ...
    },
  }],
  "paging": {
    "pageCurrent": 0,
    "itemMin": 0,
    "itemMax": 2,
    "maxNextPages": 0,
    "pageSize": 100
  }
}

I'd like to deserialize it to be a list (or IEnumerable) of objects typed so that there's an Id property (perhaps not all fields have to be parsed in to the object).

When I try to do that using the following code:

List<Some> somes = JsonConvert.DeserializeObject<List<Some>>(dataAbove);

class Some { public String Id { get; set; } }

I get a long error message about me not being using the correct type and array and a bunch of other stuff that makes me confused. Am I on the right track or did I totally went off and got lost?!

I understand it's something with the list at the root. But what?! Or at least - what should I google for?!

Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[ScriveProxy.Template]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\u000d\u000aTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\u000d\u000aPath 'list', line 1, position 8."

It can't be this one because the outer brackets are curly not squary...

In this solution, we end up with a single object, not an array, so it's not what I'm aiming for neither.

Community
  • 1
  • 1
Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438

2 Answers2

4

In your case, "list" is an array of "fields" objects.

"paging" is an object.

Both "list"` and "paging"` are in an un-named root object.

Working dotNetFiddle: https://dotnetfiddle.net/4qLTvq

See the output in the console pane of the fiddle above.

Here's How you should declare your Classes for Deserializing this particular JSON into C# Classes.

public class Fields
{
    public string id { get; set; }
}

public class TheFields
{
    public Fields fields { get; set; }
}

public class Paging
{
    public int pageCurrent { get; set; }
    public int itemMin { get; set; }
    public int itemMax { get; set; }
    public int maxNextPages { get; set; }
    public int pageSize { get; set; }
}

public class RootObject
{
    [Newtonsoft.Json.JsonPropertyAttribute("list")] 
    public List<TheFields> FieldsList { get; set; }
    public Paging paging { get; set; }
}

And here's how you would deserialize the whole thing.

var rootObject = JsonConvert.DeserializeObject<RootObject>(jsonString);

Since List is a keyword, and to avoid confusion and collision, I changed it's Name to FieldsList and also renamed the List class to TheFields class. You may choose any other name(s) that you feel is appropriate.

Explanation on Object vs Array

An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

object

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

array

Source: http://www.json.org/

Community
  • 1
  • 1
Shiva
  • 20,575
  • 14
  • 82
  • 112
  • Do I control how the data string is fetched and formatted at the call time? Or is it so that if the server gives me outer curleys I can't get them as squareys, period? +1 for pedagogical approach and images! – Konrad Viltersten Nov 13 '14 at 22:06
  • Usually the caller (your code) does not have control over the sender (the server / code sending the JSON). I use this site => http://json2csharp.com/ to generate the correct C# classes with nesting from a given JSON (should be valid) string. – Shiva Nov 13 '14 at 22:16
  • I added a working dotNetFiddle to my answer. Check it out. Everything works nicely! https://dotnetfiddle.net/4qLTvq – Shiva Nov 13 '14 at 22:30
  • Oh, after watching like a moron for an hours I realize the problem - my *DataMember* isn't working... You mean that I have to use *JsonPropertyAttribute* and not *DataMember* to map *list* to *Donkey*?! Such an information should be presented somewhere... Like a documentation or something... :) However, I went *[JsonProperty("list")]* instead. Is that the same or will it come back and bite me too? – Konrad Viltersten Nov 13 '14 at 23:05
  • Read this - "JsonProperty Vs DataMember". http://stackoverflow.com/a/20579372/325521 . Short answer, for serializing and deserializing JSON and naming the Properties, use `JsonProperty`. Also, don't beat yourself up and be so hard on yourself. The key thing is that you figured it out yourself, so you will never forget this ever again :) – Shiva Nov 14 '14 at 00:30
  • Great answer. If I wouldn't be so stingy with my rep, I'd bounty you, for sure, hahaha. One thing in the images, though, that seems to differ from what I expected - it says that the combo is *string:value* but all the JSON structures I've seen are *string:string*... Technically, the other string is a value but I've only seen string typed values ("1", not 1). Is my reference horizon too narrow? – Konrad Viltersten Nov 14 '14 at 10:55
1

If it starts with { it's an object. If it starts with [ it's an array.