【问题标题】:JsonSerializationException: Cannot deserialize the current JSON objectJsonSerializationException:无法反序列化当前 JSON 对象
【发布时间】:2017-11-26 06:32:57
【问题描述】:

我对 C# 和 Visualstudio2017 非常陌生,并且已经坚持了几个星期。搜索网络但没有找到与此相关的我可以正确理解的结果。我想要做的是从 https://zkillboard.com/api/stats/characterID/224802743/ 然后将其转换为可用数据,我可以在某些文本框中获取并显示某些数据。我使用https://quicktype.io/ 将 json 转换为 C# 数组。

MainForm.cs

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Net;
using ZKILLBOARDDATA;



namespace MainProgram
{

    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.ResizeRedraw, true);

        }


        public async void Btn_submit_ClickAsync(object sender, EventArgs e)
        {
             var remoteUri = "https://zkillboard.com/api/stats/characterID/224802743/";
             var myWebClient = new WebClient();
             myWebClient.Headers.Add("user-agent", "C# App testing");
             var jsonString = await myWebClient.DownloadStringTaskAsync(remoteUri);
             var data = GettingStarted.FromJson(jsonString);
        }   
    }
}

Zkill.cs

using Newtonsoft.Json;
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using ZKILLBOARDDATA;
//
//    var data = GettingStarted.FromJson(jsonString);
//
namespace ZKILLBOARDDATA
{

    public partial class GettingStarted
    {
        [JsonProperty("attackers")]
        public Attacker[] Attackers { get; set; }

        [JsonProperty("killmail_id")]
        public long KillmailId { get; set; }

        [JsonProperty("killmail_time")]
        public string KillmailTime { get; set; }

        [JsonProperty("moon_id")]
        public long? MoonId { get; set; }

        [JsonProperty("solar_system_id")]
        public long SolarSystemId { get; set; }

        [JsonProperty("victim")]
        public Victim Victim { get; set; }

        [JsonProperty("war_id")]
        public long? WarId { get; set; }

        [JsonProperty("zkb")]
        public Zkb Zkb { get; set; }
    }

    public partial class Zkb
    {
        [JsonProperty("awox")]
        public bool Awox { get; set; }

        [JsonProperty("fittedValue")]
        public double FittedValue { get; set; }

        [JsonProperty("hash")]
        public string Hash { get; set; }

        [JsonProperty("locationID")]
        public long LocationID { get; set; }

        [JsonProperty("npc")]
        public bool Npc { get; set; }

        [JsonProperty("points")]
        public long Points { get; set; }

        [JsonProperty("solo")]
        public bool Solo { get; set; }

        [JsonProperty("totalValue")]
        public double TotalValue { get; set; }
    }

    public partial class Victim
    {
        [JsonProperty("alliance_id")]
        public long? AllianceId { get; set; }

        [JsonProperty("character_id")]
        public long? CharacterId { get; set; }

        [JsonProperty("corporation_id")]
        public long CorporationId { get; set; }

        [JsonProperty("damage_taken")]
        public long DamageTaken { get; set; }

        [JsonProperty("items")]
        public Item[] Items { get; set; }

        [JsonProperty("position")]
        public Position Position { get; set; }

        [JsonProperty("ship_type_id")]
        public long ShipTypeId { get; set; }
    }

    public partial class Position
    {
        [JsonProperty("x")]
        public double X { get; set; }

        [JsonProperty("y")]
        public double Y { get; set; }

        [JsonProperty("z")]
        public double Z { get; set; }
    }

    public partial class Item
    {
        [JsonProperty("flag")]
        public long Flag { get; set; }

        [JsonProperty("item_type_id")]
        public long ItemTypeId { get; set; }

        [JsonProperty("items")]
        public Item[] Items { get; set; }

        [JsonProperty("quantity_destroyed")]
        public long? QuantityDestroyed { get; set; }

        [JsonProperty("quantity_dropped")]
        public long? QuantityDropped { get; set; }

        [JsonProperty("singleton")]
        public long Singleton { get; set; }
    }

    public partial class Attacker
    {
        [JsonProperty("alliance_id")]
        public long? AllianceId { get; set; }

        [JsonProperty("character_id")]
        public long? CharacterId { get; set; }

        [JsonProperty("corporation_id")]
        public long? CorporationId { get; set; }

        [JsonProperty("damage_done")]
        public long DamageDone { get; set; }

        [JsonProperty("faction_id")]
        public long? FactionId { get; set; }

        [JsonProperty("final_blow")]
        public bool FinalBlow { get; set; }

        [JsonProperty("security_status")]
        public double SecurityStatus { get; set; }

        [JsonProperty("ship_type_id")]
        public long? ShipTypeId { get; set; }

        [JsonProperty("weapon_type_id")]
        public long? WeaponTypeId { get; set; }
    }

    public partial class GettingStarted
    {
        public static GettingStarted[] FromJson(string json) => JsonConvert.DeserializeObject<GettingStarted[]>(json, Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this GettingStarted[] self) => JsonConvert.SerializeObject(self, Converter.Settings);
    }

    public class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
        };
    }
}

这是我从 VS2017 收到的错误消息。

JsonSerializationException: 无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型“ZKILLBOARDDATA.GettingStarted[]”,因为该类型需要 JSON 数组(例如 [1,2,3])正确反序列化。

要修复此错误,要么将 JSON 更改为 JSON 数组(例如 [1,2,3]),要么将反序列化类型更改为正常的 .NET 类型(例如,不是像整数这样的原始类型,而不是可以从 JSON 对象反序列化的集合类型(如数组或列表)。 JsonObjectAttribute 也可以添加到类型中,以强制它从 JSON 对象反序列化。

路径“allTimeSum”,第 1 行,位置 14。

【问题讨论】:

  • 鉴于您提供的信息,我觉得错误消息为您提供了尽可能好的答案。您的 JSON 源显然不是数组。
  • 我需要做什么才能使其正常工作。我尝试过使用不起作用的 c# 内置特殊粘贴。我迷路了。
  • Web 请求返回一个 JSON object(以 { 开头)但您的反序列化调用需要一个 JSON array(以 [) 开头(异常信息非常清楚)。似乎您想从返回的 JSON 中挑选一些数据,但是您的代码没有足够的魔力来完成该任务
  • 我刚刚检查了来自链接的 JSON 响应,在该响应的任何位置都可以找到没有的 GettingStarted 属性。

标签: c# serialization json.net httpclient webclient


【解决方案1】:

试试这个

     var remoteUri = "https://zkillboard.com/api/stats/characterID/224802743/";
     var myWebClient = new WebClient();
     myWebClient.Headers.Add("user-agent", "C# App testing");
     myWebClient.Headers.Add("content-type", "application/json");

     var jsonString = myWebClient.DownloadStringTaskAsync(remoteUri).Result;

     var obj = JsonConvert.DeserializeObject(jsonString);
     //OR
     var obj = JsonConvert.DeserializeObject<YourModel>(jsonString);

我认为你的模型中不需要这个

public partial class GettingStarted
    {
        public static GettingStarted[] FromJson(string json) => JsonConvert.DeserializeObject<GettingStarted[]>(json, Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this GettingStarted[] self) => JsonConvert.SerializeObject(self, Converter.Settings);
    }

    public class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
        };
    }

【讨论】:

  • 可以使用obj.someProperty之类的数据,在文本区设置。例如:textbox1.setText 或 textbox1.innerHtml = obj.someProeprty;
  • 您建议我删除的代码是由quicktype.io 生成的,类和jsonobjects 也是如此。我把它留在我的代码中并替换了你让我尝试的代码,我不再收到那个错误,但我现在得到了。 (此方法缺少“等待”运算符,将同步运行。)但是我如何将收到的某些数据放入某些文本框等中。
  • 它是一个 Windows 窗体应用程序而不是 WPF 顺便说一句。 innerHtml 未重新调整。 setText 也不是。我也试过 OutputBox.Text = obj.Zkb.Points; (但它的返回错误,不能隐式转换类型 'long' 到 'string')
  • 我不知道你在用什么,所以我只是给了你一般的建议,你可以如何在文本字段中设置文本。你缺少基本的东西。你可以设置像 OutputBox.Text = obj.Zkb.Points.toString() 这样的值。
  • github.com/kovacev/EVE-LOCAL-SCAN 我把它放在 Github 上,你可以试试。我似乎无法让它正常工作
【解决方案2】:

我遇到了同样的问题;我通过使用新的默认 System.Text.Json.JsonSerializer.Deserialize 而不是 Newtonsoft 解决了这个问题

using System.Text.Json;    
var obj = JsonSerializer.Deserialize<YourMODEL>(jsonStr);

附言https://quicktype.io 很棒(尽管对于 C# 来说似乎有些过时了);我也尝试过http://json2csharp.com,但我的 json 文件很大而且冻结了。

有时(尤其是对于深度嵌套的复杂 json)quicktype 不添加列表/数组类型;例如MyObj 而不是 List&lt;MyObj&gt;。 有时可以通过先选择 T[] 然后从网站的生成菜单选项Use T[] or List&lt;T&gt; 中选择 List 来“修复”它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    相关资源
    最近更新 更多