0

I am new to using the Json format with serializing and deserializing, I am using Json.Net. As a little activity I decided to use the API from a game that I play to retrieve some simple statistics. However, I am trying to put this Json into classes (created by json2csharp) but I get the exception.

Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type   'System.Collections.Generic.List`1[TornCityAPI.PlayerStatistics.Stats+RootObject]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

and here is the code.

using Microsoft.Win32;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Windows.Forms;

namespace TornCityAPI
{
    public partial class Form_Main : Form
    {
        // to hold the users api key
        private string apiKey;
        public string APIKey
        {
            get { return apiKey; }
            set { apiKey = value; }
        }

        // location in the registry
        private string registryLocation = @"HKEY_CURRENT_USER\TornCityAPI\Watch_App";
        public string RegistryLocation
        {
            get { return registryLocation; }
        }

        // the url which will be used to retrive information
        private string apiUrl = "https://api.torn.com/user/?selections=&key=";
        public string ApiUrl
        {
            get { return apiUrl; }
            set { apiUrl = value; }
        }

        // in case of a network disconnect, we could server the previous results instead.
        private string previousTornStats;
        public string PreviousTronStats
        {
            get { return previousTornStats; }
            set { previousTornStats = value; }
        }

        public Form_Main()
        {
            InitializeComponent();
        }

        private void Form_Main_Load(object sender, EventArgs e)
        {
            CheckNetworkConnection();

            // if the api key does not exists within the registry
            if (Registry.GetValue(registryLocation, "Watch_App", null) == null)
            {
                // ask the user to insert theirs and open the form to allow that
                MessageBox.Show("Please enter your torn API key!");
                Form_APIKey apiWindow = new Form_APIKey();
                apiWindow.ShowDialog(this);
            }
            // otherwise
            else
            {
                // connect the url with the api key to get the full, working url to get the information 
                APIKey = (string)Registry.GetValue(registryLocation, "Watch_App", null);
                ApiUrl += APIKey;
                MessageBox.Show(apiUrl);
            }
        }

        private void timer_UpdateStats_Tick(object sender, EventArgs e)
        {
            CheckNetworkConnection();
            UpdateTornStats();
        }

        void UpdateTornStats()
        {
            using (var webClient = new WebClient())
            {
                var json = new WebClient().DownloadString(ApiUrl);
                var list = JsonConvert.DeserializeObject<List<PlayerStatistics.Stats.RootObject>>(json);
                Console.WriteLine(list.Count);
            }
        }

        void CheckNetworkConnection()
        {
            // if they are not connected to the internet
            if (NetworkInterface.GetIsNetworkAvailable() == false)
            {
                Console.WriteLine("You are not connected to the internet!" + "\n" + "Please connect and restart!");
                return;
            }
        }
    }
}

Specifically:

void UpdateTornStats()
        {
            using (var webClient = new WebClient())
            {
                var json = new WebClient().DownloadString(ApiUrl);
                var list = JsonConvert.DeserializeObject<List<PlayerStatistics.Stats.RootObject>>(json);
                Console.WriteLine(list.Count);
            }
        }

Here is the class I try to put it into.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TornCityAPI.PlayerStatistics
{
    class Stats
    {
    public class Life
    {
        public int current { get; set; }
        public int maximum { get; set; }
        public int increment { get; set; }
        public int interval { get; set; }
        public int ticktime { get; set; }
        public int fulltime { get; set; }
    }

    public class Job
    {
        public string position { get; set; }
        public int company_id { get; set; }
        public string company_name { get; set; }
    }

    public class Faction
    {
        public string position { get; set; }
        public int faction_id { get; set; }
        public int days_in_faction { get; set; }
        public string faction_name { get; set; }
    }

    public class Married
    {
        public int spouse_id { get; set; }
        public string spouse_name { get; set; }
        public int duration { get; set; }
    }

    public class Icons
    {
        public string icon6 { get; set; }
        public string icon3 { get; set; }
        public string icon8 { get; set; }
        public string icon27 { get; set; }
        public string icon9 { get; set; }
    }

    public class RootObject
    {
        public string rank { get; set; }
        public int level { get; set; }
        public string gender { get; set; }
        public string property { get; set; }
        public string signup { get; set; }
        public int awards { get; set; }
        public int friends { get; set; }
        public int enemies { get; set; }
        public int forum_posts { get; set; }
        public int karma { get; set; }
        public int age { get; set; }
        public string role { get; set; }
        public int donator { get; set; }
        public int player_id { get; set; }
        public string name { get; set; }
        public int property_id { get; set; }
        public string last_action { get; set; }
        public Life life { get; set; }
        public List<string> status { get; set; }
        public Job job { get; set; }
        public Faction faction { get; set; }
        public Married married { get; set; }
        public Icons icons { get; set; }
    }
}
}

I dont really know how to lay this out or what class should be created from the Json. (However I assume its the root as it has references to the other classes)

Finally, here is the Json which is downloaded to a string:

{
"rank": "Reasonable Punchbag",
"level": 22,
"gender": "Male",
"property": "Ranch",
"signup": "2013-08-01 07:59:43",
"awards": 58,
"friends": 2,
"enemies": 2,
"forum_posts": 25,
"karma": 4,
"age": 1234,
"role": "Civilian",
"donator": 1,
"player_id": 1761543,
"name": "GamingAnonymous",
"property_id": 16693,
"last_action": "18 minutes ago",
"life": {
    "current": 429,
    "maximum": 1072,
    "increment": 53,
    "interval": 300,
    "ticktime": 258,
    "fulltime": 3858
},
"status": [
    "In hospital for 3 hrs 4 mins - Hospitalized by someone",
    ""
],
"job": {
    "position": "Employee",
    "company_id": 61582,
    "company_name": "streamTV - hiring 33k man"
},
"faction": {
    "position": "Member",
    "faction_id": 17845,
    "days_in_faction": 268,
    "faction_name": "The Watchers"
},
"married": {
    "spouse_id": 2024099,
    "spouse_name": "Anonymous_Hugo",
    "duration": 62
},
"icons": {
    "icon6": "Male",
    "icon3": "Donator",
    "icon8": "Married - To Anonymous_Hugo",
    "icon27": "Company - Employee of streamTV - hiring 33k man (Television Network)",
    "icon9": "Faction - Member of The Watchers",
    "icon15": "Hospital - Hospitalized by someone - 03:04:17 "
}
}

Any help would be greatly appreciated, thanks.

2
  • Why do you try to deserialize it in a list of RootObject when the JSON you get back is just one object? Get rid of the List<..> and it'll work. (var list = JsonConvert.DeserializeObject<List<PlayerStatistics.Stats.RootObject>>(json);) Commented Dec 17, 2016 at 18:00
  • That first block of code isnt really needed - just makes the Q longer than need be. The error message is kind of self explanatory. Commented Dec 17, 2016 at 18:01

1 Answer 1

1

The error message is pretty straightforward. You're trying to deserialize object to List of RootObject. Use this snippet:

void UpdateTornStats()
{
    using (var webClient = new WebClient())
    {
        var json = new WebClient().DownloadString(ApiUrl);
        var list = JsonConvert.DeserializeObject<PlayerStatistics.Stats.RootObject>(json);
        Console.WriteLine(list.Count);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

haha Thanks! I knew it would be something silly, it usually is when learning something new. (And thanks to the people in the 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.