C# 无法将 JSON 数组反序列化为类型 - Json.NET
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9452901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cannot deserialize JSON array into type - Json.NET
提问by tugberk
I am trying to deserialize a json data into a model class but I am failing. Here is what I do:
我正在尝试将 json 数据反序列化为模型类,但失败了。这是我所做的:
public CountryModel GetCountries() {
using (WebClient client = new WebClient()) {
var result = client.DownloadString("http://api.worldbank.org/incomeLevels/LIC/countries?format=json");
var output = JsonConvert.DeserializeObject<List<CountryModel>>(result);
return output.First();
}
}
This is how my model looks like:
这是我的模型的样子:
public class CountryModel
{
public int Page { get; set; }
public int Pages { get; set; }
public int Per_Page { get; set; }
public int Total { get; set; }
public List<Country> Countries { get; set; }
}
public class Country
{
public int Id { get; set; }
public string Iso2Code { get; set; }
public string Name { get; set; }
public Region Region { get; set; }
}
public class Region
{
public int Id { get; set; }
public string Value { get; set; }
}
You can see the Json I am getting here: http://api.worldbank.org/incomeLevels/LIC/countries?format=json
你可以看到我在这里得到的 Json:http: //api.worldbank.org/incomeLevels/LIC/countries?format=json
This is the error I get:
这是我得到的错误:
Cannot deserialize JSON array into type 'Mvc4AsyncSample.Models.CountryModel'. Line 1, position 1.
无法将 JSON 数组反序列化为“Mvc4AsyncSample.Models.CountryModel”类型。第 1 行,位置 1。
采纳答案by Paul Tyng
You have to write a custom JsonConverter:
你必须写一个自定义JsonConverter:
public class CountryModelConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
if (objectType == typeof(CountryModel))
{
return true;
}
return false;
}
public override object ReadJson(JsonReader reader, Type objectType
, object existingValue, JsonSerializer serializer)
{
reader.Read(); //start array
//reader.Read(); //start object
JObject obj = (JObject)serializer.Deserialize(reader);
//{"page":1,"pages":1,"per_page":"50","total":35}
var model = new CountryModel();
model.Page = Convert.ToInt32(((JValue)obj["page"]).Value);
model.Pages = Convert.ToInt32(((JValue)obj["pages"]).Value);
model.Per_Page = Int32.Parse((string) ((JValue)obj["per_page"]).Value);
model.Total = Convert.ToInt32(((JValue)obj["total"]).Value);
reader.Read(); //end object
model.Countries = serializer.Deserialize<List<Country>>(reader);
reader.Read(); //end array
return model;
}
public override void WriteJson(JsonWriter writer, object value
, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
And tag the CountryModelwith that converter (I also had to switch some intto string):
并CountryModel用该转换器标记(我还必须将一些转换int为string):
[JsonConverter(typeof(CountryModelConverter))]
public class CountryModel
{
public int Page { get; set; }
public int Pages { get; set; }
public int Per_Page { get; set; }
public int Total { get; set; }
public List<Country> Countries { get; set; }
}
public class Country
{
public string Id { get; set; }
public string Iso2Code { get; set; }
public string Name { get; set; }
public Region Region { get; set; }
}
public class Region
{
public string Id { get; set; }
public string Value { get; set; }
}
Then you should be able to deserialize like this:
然后你应该能够像这样反序列化:
var output = JsonConvert.DeserializeObject<CountryModel>(result);
回答by svick
This looks like a (not very good) attempt at representing XML in JSON. The JSON looks like this:
这看起来像是在 JSON 中表示 XML 的(不是很好)尝试。JSON 如下所示:
[
{
"page": 1,
…
},
[
{
"id": "AFG",
"name": "Afghanistan",
…
},
{
"id": "BDI",
"name": "Burundi",
…
},
…
]
]
While a reasonable JSON (that would incidentally map to your model nicely) would look like this:
虽然一个合理的 JSON(它会很好地映射到你的模型)看起来像这样:
{
"page": 1,
…,
"countries": [
{
"id": "AFG",
"name": "Afghanistan",
…
},
{
"id": "BDI",
"name": "Burundi",
…
},
…
]
}
If you are sure you want to use JSON (and not XML), you can do it by first deserializing the JSON into JSON.NET's object model and then deserialize that into your model:
如果您确定要使用 JSON(而不是 XML),您可以先将 JSON 反序列化为 JSON.NET 的对象模型,然后将其反序列化为您的模型:
var json = client.DownloadString("http://api.worldbank.org/incomeLevels/LIC/countries?format=json");
var array = (JArray)JsonConvert.DeserializeObject(json);
var serializer = new JsonSerializer();
var countryModel = serializer.Deserialize<CountryModel>(array[0].CreateReader());
countryModel.Countries = serializer.Deserialize<List<Country>>(array[1].CreateReader());
return countryModel;
Don't forget to change your Idproperties to string, because that's what they are.
不要忘记将您的Id属性更改为string,因为它们就是这样。
回答by ChrisS
Your model doesn't match the JSON structure. It looks like your missing the last 6 properties.
您的模型与 JSON 结构不匹配。看起来您缺少最后 6 个属性。
{
"id": "AFG",
"iso2Code": "AF",
"name": "Afghanistan",
"region": {
"id": "SAS",
"value": "South Asia"
},
"adminregion": {
"id": "SAS",
"value": "South Asia"
},
"incomeLevel": {
"id": "LIC",
"value": "Low income"
},
"lendingType": {
"id": "IDX",
"value": "IDA"
},
"capitalCity": "Kabul",
"longitude": "69.1761",
"latitude": "34.5228"
}
}

