无法对json足球数据进行反序列化

时间:2015-05-12 18:26:10

标签: c# winforms rest

我想创建一个使用football-data.org数据的Windows窗体应用程序。这是我第一次使用restful / JSON,而且我被困了。

当我试图获得football-data.org提供的所有联赛时,这是你从football-data.org api获得的回复:response

我使用以下代码来获取所有正确的数据:(lbResultBox是一个列表框)

private void btAllLeagues_Click(object sender, EventArgs e)
{
    lbResultBox.Items.Clear();
    List<Leagues> LL = GetLeagues("soccerseasons");
    foreach (var item in LL)
    {
       lbResultBox.Items.Add(item.caption);
    }
}

public static List<Leagues> GetLeagues(string endurl)
{
    var syncClient = new WebClient();
    var content = syncClient.DownloadString(baseurl + endurl);
    return JsonConvert.DeserializeObject<List<Leagues>>(content);
}

public class Leagues
{
    public IDictionary<string,LeagueLinks> _links { get; set; }
    public string caption { get; set; }
    public string league { get; set; }
    public string year { get; set; }
    public string numberOfTeams { get; set; }
    public string numberOfGames { get; set; }
    public string lastUpdated { get; set; }
}

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

这很有效。

但是当我试图从联盟中获得所有球队时,这是我从api获得的response。我使用这段代码:

private void btAllTeams_Click(object sender, EventArgs e)
{
    List<LeagueTeams> LT = GetLeagueTeams("soccerseasons/" + id + "/teams");
}

public static List<LeagueTeams> GetLeagueTeams(string endurl)
{
   var syncClient = new WebClient();
   var content = syncClient.DownloadString(baseurl + endurl);
   return JsonConvert.DeserializeObject<List<LeagueTeams>>(content);
}

public class LeagueTeams
{
    public IDictionary<string, LeagueLinks> _links { get; set; }
    public string count { get; set; }
    public IDictionary<string, LeagueTeam> teams { get; set; }
}

public class LeagueTeam
{
    public IDictionary<string, TeamLinks> _links { get; set; }
    public string name { get; set; }
    public string code { get; set; }
    public string shortName { get; set; }
    public string squadMarketValue { get; set; }
    public string crestUrl { get; set; }
}
public class TeamLinks
{
    public string href { get; set; }
}

但我收到以下错误:

  

类型&#39; Newtonsoft.Json.JsonSerializationException的未处理异常&#39;发生在Newtonsoft.Json.dll中   附加信息:无法将当前JSON数组(例如[1,2,3])反序列化为类型System.Collections.Generic.IDictionary`2 [System.String,FootballTestApplication.LeagueTeam]&#39;因为该类型需要一个JSON对象(例如{&#34; name&#34;:&#34; value&#34;})才能正确反序列化。

当我看到api给我的回应时,我可以看出响应开始的方式有所不同。通过收集所有联赛,它以括号([])开始和结束,但是当在联赛中收集球队时,它不会以括号开始或结束。当我自己添加括号时,我仍然会收到错误。这是我添加括号的方式:

return JsonConvert.DeserializeObject<List<LeagueTeams>>("["+content+"]");

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

问题在于返回的JSON是 NOT ArrayListDictionary或其他Enumerable,而是它自己的object

如果我们从该API链接中获取您的JSON并逐个元素地浏览它,我们就会发现您的Type错误。

您告诉JSON Serializer根对象是List<LeagueTeams>,但事实并非如此。它实际上是一个LeagueTeams对象。

如果我们对反序列化程序进行了修改,并且我们对您的LeagueTeams类进行了一些修改(主要是因为您将links属性反序列化错误的事实),那么您已经完成了设置:< / p>

public class LeagueTeams
{
    public List<IDictionary<string, string>> _links { get; set; }
    public string count { get; set; }
    public List<LeagueTeam> teams { get; set; }
}

return JsonConvert.DeserializeObject<LeagueTeams>(content);

我附上了结果图片。

Inspection of your Object

附加说明

需要注意的另一件事是:JSON到C#网站(http://json2csharp.com/ NOT 正确处理此JSON,它实际上会生成一个几乎的对象是的,但并不完全。 (虽然生成的对象仍然可以正常工作,但它并不是输入JSON的完全正确的映射。)这部分是由于生成器的故障,也是网站的故障。它尝试为根Link项生成一个两属性links元素的列表,而它应该使用字典列表来获取正确的映射。 (虽然,这有点令人费解,但这是最正确的方法。)另外需要考虑的是,是的,它确实可以获得良好的开端,但一般来说,正确的JSON处理需要对生成的对象进行更细致的检查保证正确。