Search code examples
c#jsonserializationjson-deserialization

json to c# deserialization with json.net


I know there has been countless posts about json deserialization, but I have followed most of the posts answers, and they haven't worked out. I think my main issue is I can't seem to wrap my head around how Json actually is built up structure-wise.

I have following Json string from an API:

{
  "totalCount_str": "3",
  "items": [
    {
      "standing": 10,
      "corporation": {
        "name": "borkedLabs",
        "isNPC": false,
        "href": "https://crest-tq.eveonline.com/corporations/98046548/",
        "id_str": "98046548",
        "logo": {
          "32x32": {
            "href": "http://imageserver.eveonline.com/Corporation/98046548_32.png"
          },
          "64x64": {
            "href": "http://imageserver.eveonline.com/Corporation/98046548_64.png"
          },
          "128x128": {
            "href": "http://imageserver.eveonline.com/Corporation/98046548_128.png"
          },
          "256x256": {
            "href": "http://imageserver.eveonline.com/Corporation/98046548_256.png"
          }
        },
        "id": 98046548
      },
      "href": "https://crest-tq.eveonline.com/characters/94512721/contacts/98046548/",
      "contact": {
        "id_str": "98046548",
        "href": "https://crest-tq.eveonline.com/corporations/98046548/",
        "name": "borkedLabs",
        "id": 98046548
      },
      "contactType": "Corporation"
    },
    {
      "standing": 10,
      "character": {
        "name": "xxxx yyyy",
        "corporation": {
          "name": "xxyshs",
          "isNPC": false,
          "href": "https://crest-tq.eveonline.com/corporations/98401169/",
          "id_str": "98401169",
          "logo": {
            "32x32": {
              "href": "http://imageserver.eveonline.com/Corporation/98401169_32.png"
            },
            "64x64": {
              "href": "http://imageserver.eveonline.com/Corporation/98401169_64.png"
            },
            "128x128": {
              "href": "http://imageserver.eveonline.com/Corporation/98401169_128.png"
            },
            "256x256": {
              "href": "http://imageserver.eveonline.com/Corporation/98401169_256.png"
            }
          },
          "id": 98401169
        },
        "isNPC": false,
        "href": "https://crest-tq.eveonline.com/characters/95161569/",
        "capsuleer": {
          "href": "https://crest-tq.eveonline.com/characters/95161569/capsuleer/"
        },
        "portrait": {
          "32x32": {
            "href": "http://imageserver.eveonline.com/Character/95161569_32.jpg"
          },
          "64x64": {
            "href": "http://imageserver.eveonline.com/Character/95161569_64.jpg"
          },
          "128x128": {
            "href": "http://imageserver.eveonline.com/Character/95161569_128.jpg"
          },
          "256x256": {
            "href": "http://imageserver.eveonline.com/Character/95161569_256.jpg"
          }
        },
        "id": 95161569,
        "id_str": "95161569"
      },
      "contact": {
        "id_str": "95161569",
        "href": "https://crest-tq.eveonline.com/characters/95161569/",
        "name": "xxxx yyyy",
        "id": 95161569
      },
      "href": "https://crest-tq.eveonline.com/characters/94512769/contacts/95161569/",
      "contactType": "Character",
      "watched": false,
      "blocked": false
    },
    {
      "standing": -10,
      "alliance": {
        "id_str": "99000003",
        "href": "http://crest.regner.dev/alliances/99000003/",
        "id": 99000003,
        "name": "One One Corporation Alliance"
      },
      "href": "http://crest.regner.dev/characters/90000001/contacts/99000003/",
      "contact": {
        "id_str": "99000003",
        "href": "http://crest.regner.dev/alliances/99000003/",
        "name": "One One Corporation Alliance",
        "id": 99000003
      },
      "contactType": "Alliance"
    }
  ],
  "pageCount": 1,
  "pageCount_str": "1",
  "totalCount": 3
}

Note that the items array can contain any number of "contacts".

By using http://json2csharp.com/ I have converted it to classes in C# as following:

public class Contacts
{
    public string totalCount_str { get; set; }
    public Item[] items { get; set; }
    public int pageCount { get; set; }
    public string pageCount_str { get; set; }
    public int totalCount { get; set; }
}

public class Item
{
    public int standing { get; set; }
    public Alliance alliance { get; set; }
    public string href { get; set; }
    public Contact contact { get; set; }
    public string contactType { get; set; }
    public Character character { get; set; }
    public bool watched { get; set; }
    public bool blocked { get; set; }
}

public class Alliance
{
    public string id_str { get; set; }
    public string href { get; set; }
    public int id { get; set; }
    public string name { get; set; }
}

public class Contact
{
    public string id_str { get; set; }
    public string href { get; set; }
    public string name { get; set; }
    public int id { get; set; }
}

public class Character
{
    public string name { get; set; }
    public Corporation corporation { get; set; }
    public bool isNPC { get; set; }
    public string href { get; set; }
    public Capsuleer capsuleer { get; set; }
    public Portrait portrait { get; set; }
    public int id { get; set; }
    public string id_str { get; set; }
}

public class Corporation
{
    public string name { get; set; }
    public bool isNPC { get; set; }
    public string href { get; set; }
    public string id_str { get; set; }
    public Logo logo { get; set; }
    public int id { get; set; }
}

public class Logo
{
    public _32X32 _32x32 { get; set; }
    public _64X64 _64x64 { get; set; }
    public _128X128 _128x128 { get; set; }
    public _256X256 _256x256 { get; set; }
}

public class _32X32
{
    public string href { get; set; }
}

public class _64X64
{
    public string href { get; set; }
}

public class _128X128
{
    public string href { get; set; }
}

public class _256X256
{
    public string href { get; set; }
}

public class Capsuleer
{
    public string href { get; set; }
}

public class Portrait
{
    public _32X32 _32x32 { get; set; }
    public _64X64 _64x64 { get; set; }
    public _128X128 _128x128 { get; set; }
    public _256X256 _256x256 { get; set; }
}

And then trying to deserialize it with:

List<Contacts> tempList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Contacts>>(response.Content);

I appreciate any help that could get me on the right tracks. I get an error currently when trying this way:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ContactWatchlister.Models.Contacts]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To 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<T>) 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.
Path 'totalCount_str', line 1, position 18.

I am currently stuck as I don't get why it is having trouble understanding "totalCount_str" into a string.

I have tried to use [JsonProperty("attribute")] on all attributes in my classes to model it correct, but same error.

I'm pretty sure I am doing something rather simple, wrong, but I can't wrap my head around it. Hope you can help! :-)


Solution

  • If response.Content contains the JSON string you described I think the statement should be:

    var tempList = Newtonsoft.Json.JsonConvert.DeserializeObject<Contacts>(response.Content);
    

    Your JSON has the "totalCount_str", items, pageCount, pageCount_str and totalCount fields in the outermost "level", so it can only be deserialized into a class that has those properties (or properties with correct JsonAttributes that correspond to those fieldnames).

    The one you tried would work with the following JSON, where the outermost entity is an array:

    [   {
        "totalCount_str": "3",
        "items": [
          {
            "standing": 10,
            "corporation": {
              "name": "borkedLabs",
              "isNPC": false,
              "href": "https://crest-tq.eveonline.com/corporations/98046548/",
              "id_str": "98046548",
              "logo": {
                "32x32": {
                  "href": "http://imageserver.eveonline.com/Corporation/98046548_32.png"
                },
                "64x64": {
                  "href": "http://imageserver.eveonline.com/Corporation/98046548_64.png"
                },
                "128x128": {
                  "href": "http://imageserver.eveonline.com/Corporation/98046548_128.png"
                },
                "256x256": {
                  "href": "http://imageserver.eveonline.com/Corporation/98046548_256.png"
                }
              },
              "id": 98046548
            },
            "href": "https://crest-tq.eveonline.com/characters/94512721/contacts/98046548/",
            "contact": {
              "id_str": "98046548",
              "href": "https://crest-tq.eveonline.com/corporations/98046548/",
              "name": "borkedLabs",
              "id": 98046548
            },
            "contactType": "Corporation"
          },
          {
            "standing": 10,
            "character": {
              "name": "xxxx yyyy",
              "corporation": {
                "name": "xxyshs",
                "isNPC": false,
                "href": "https://crest-tq.eveonline.com/corporations/98401169/",
                "id_str": "98401169",
                "logo": {
                  "32x32": {
                    "href": "http://imageserver.eveonline.com/Corporation/98401169_32.png"
                  },
                  "64x64": {
                    "href": "http://imageserver.eveonline.com/Corporation/98401169_64.png"
                  },
                  "128x128": {
                    "href": "http://imageserver.eveonline.com/Corporation/98401169_128.png"
                  },
                  "256x256": {
                    "href": "http://imageserver.eveonline.com/Corporation/98401169_256.png"
                  }
                },
                "id": 98401169
              },
              "isNPC": false,
              "href": "https://crest-tq.eveonline.com/characters/95161569/",
              "capsuleer": {
                "href": "https://crest-tq.eveonline.com/characters/95161569/capsuleer/"
              },
              "portrait": {
                "32x32": {
                  "href": "http://imageserver.eveonline.com/Character/95161569_32.jpg"
                },
                "64x64": {
                  "href": "http://imageserver.eveonline.com/Character/95161569_64.jpg"
                },
                "128x128": {
                  "href": "http://imageserver.eveonline.com/Character/95161569_128.jpg"
                },
                "256x256": {
                  "href": "http://imageserver.eveonline.com/Character/95161569_256.jpg"
                }
              },
              "id": 95161569,
              "id_str": "95161569"
            },
            "contact": {
              "id_str": "95161569",
              "href": "https://crest-tq.eveonline.com/characters/95161569/",
              "name": "xxxx yyyy",
              "id": 95161569
            },
            "href": "https://crest-tq.eveonline.com/characters/94512769/contacts/95161569/",
            "contactType": "Character",
            "watched": false,
            "blocked": false
          },
          {
            "standing": -10,
            "alliance": {
              "id_str": "99000003",
              "href": "http://crest.regner.dev/alliances/99000003/",
              "id": 99000003,
              "name": "One One Corporation Alliance"
            },
            "href": "http://crest.regner.dev/characters/90000001/contacts/99000003/",
            "contact": {
              "id_str": "99000003",
              "href": "http://crest.regner.dev/alliances/99000003/",
              "name": "One One Corporation Alliance",
              "id": 99000003
            },
            "contactType": "Alliance"
          }
        ],
        "pageCount": 1,
        "pageCount_str": "1",
        "totalCount": 3   } ]