我想创建一个使用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+"]");
我在这里做错了什么?
答案 0 :(得分:1)
问题在于返回的JSON是 NOT Array
,List
,Dictionary
或其他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);
我附上了结果图片。
需要注意的另一件事是:JSON到C#网站(http://json2csharp.com/) NOT 正确处理此JSON,它实际上会生成一个几乎的对象是的,但并不完全。 (虽然生成的对象仍然可以正常工作,但它并不是输入JSON的完全正确的映射。)这部分是由于生成器的故障,也是网站的故障。它尝试为根Link
项生成一个两属性links
元素的列表,而它应该使用字典列表来获取正确的映射。 (虽然,这有点令人费解,但这是最正确的方法。)另外需要考虑的是,是的,它确实可以获得良好的开端,但一般来说,正确的JSON处理需要对生成的对象进行更细致的检查保证正确。