C# - Json反序列化 - 无法反序列化Json对象

时间:2016-12-17 17:54:21

标签: c# json

我是使用Json格式进行序列化和反序列化的新手,我正在使用 Json.Net 。 作为一个小活动,我决定使用我玩的游戏中的API来检索一些简单的统计数据。 但是,我试图把这个Json放到类中(由json2csharp创建),但我得到了异常。

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.

这是代码。

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

具体做法是:

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

这是我尝试将它放入的课程。

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

我真的不知道如何解决这个问题或者应该从Json创建什么类。 (但我假设它是根,因为它引用了其他类)

最后,这是下载到字符串的Json:

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

非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:1)

错误消息非常简单。您正在尝试将对象反序列化为RootObject的List。 使用此代码段:

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