我无法反序列化从Web源检索到的JSON字符串。我收到一条错误说明以下内容:
Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}
) into type 'NewsApp.ComplexTypes.NYTimes.Keyword' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
这也适用于名为Byline的属性。以下是生成的json2csharp模型:
public class Headline
{
public string main { get; set; }
public string kicker { get; set; }
}
public class Keywords
{
public string rank { get; set; }
public string name { get; set; }
public string value { get; set; }
}
public class Byline
{
public string organization { get; set; }
public string original { get; set; }
public List<string> person { get; set; }
}
public class Multimedia
{
public string url { get; set; }
public string format { get; set; }
public int height { get; set; }
public int width { get; set; }
public string type { get; set; }
public string subtype { get; set; }
public string caption { get; set; }
public string copyright { get; set; }
}
public class Doc
{
public string web_url { get; set; }
public string snippet { get; set; }
public string lead_paragraph { get; set; }
public string @abstract { get; set; }
public string print_page { get; set; }
public List<string> blog { get; set; }
public string source { get; set; }
public Headline headline { get; set; }
public Keywords keywords { get; set; }
public string pub_date { get; set; }
public string document_type { get; set; }
public string news_desK { get; set; }
public string section_name { get; set; }
public string subsection_name { get; set; }
public Byline byline { get; set; }
public string type_of_material { get; set; }
public string _id { get; set; }
public string word_count { get; set; }
public string slideshow_credits { get; set; }
public List<Multimedia> multimedia { get; set; }
}
public class Meta
{
public int hits { get; set; }
public int time { get; set; }
public int offset { get; set; }
}
public class Response
{
public List<Doc> docs { get; set; }
public Meta meta { get; set; }
}
public class RootObject
{
public Response response { get; set; }
}
这是从API调用返回的JSON的结构。
{
"response": {
"docs": [
{
"web_url": "string",
"snippet": "string",
"lead_paragraph": "string",
"abstract": "string",
"print_page": "string",
"blog": [
""
],
"source": "string",
"headline": {
"main": "string",
"kicker": "string"
},
"keywords": {
"rank": "string",
"name": "string",
"value": "string"
},
"pub_date": "string",
"document_type": "string",
"news_desK": "string",
"section_name": "string",
"subsection_name": "string",
"byline": {
"organization": "string",
"original": "string",
"person": [
""
]
},
"type_of_material": "string",
"_id": "string",
"word_count": "string",
"slideshow_credits": "string",
"multimedia": [
{
"url": "string",
"format": "string",
"height": 0,
"width": 0,
"type": "string",
"subtype": "string",
"caption": "string",
"copyright": "string"
}
]
}
],
"meta": {
"hits": 0,
"time": 0,
"offset": 0
}
}
}
以下是我如何定义RootObject和Doc类
public class RootObject
{
public Response response { get; set; }
}
public class Doc
{
public Doc()
{
blog = new List<string>();
headline = new NYTimes.Headline();
keywords = new List<Keyword>();
multimedia = new List<Multimedia>();
byline = new Byline();
}
public string web_url { get; set; }
public string snippet { get; set; }
public string lead_paragraph { get; set; }
public string @abstract { get; set; }
public string print_page { get; set; }
public List<string> blog { get; set; }
public string source { get; set; }
public Headline headline { get; set; }
public List<Keyword> keywords { get; set; }
public string pub_date { get; set; }
public string document_type { get; set; }
public string news_desK { get; set; }
public string section_name { get; set; }
public string subsection_name { get; set; }
public Byline byline { get; set; }
public string type_of_material { get; set; }
public string _id { get; set; }
public string word_count { get; set; }
public string slideshow_credits { get; set; }
public List<Multimedia> multimedia { get; set; }
}
这是一个小样本数据集。
{
"copyright": "Copyright (c) 2013 The New York Times Company. All Rights Reserved.",
"response": {
"meta": {
"hits": 7644
},
"docs": [{
"web_url": "https://www.nytimes.com/slideshow/2016/01/01/nytnow/the-week-on-instagram.html",
"snippet": "Photos posted on @nytimes during the last week of 2015 took followers from an island in Antarctica to Times Square, before the ball dropped....",
"lead_paragraph": "Photos posted on @nytimes during the last week of 2015 took followers from an island in Antarctica to Times Square, before the ball dropped.",
"abstract": null,
"print_page": null,
"blog": [],
"source": "The New York Times",
"multimedia": [{
"width": 190,
"url": "images/2016/01/01/nytnow/the-week-on-instagram-slide-8Y3Z/the-week-on-instagram-slide-8Y3Z-thumbWide.jpg",
"height": 126,
"subtype": "wide",
"legacy": {
"wide": "images/2016/01/01/nytnow/the-week-on-instagram-slide-8Y3Z/the-week-on-instagram-slide-8Y3Z-thumbWide.jpg",
"wideheight": "126",
"widewidth": "190"
},
"type": "image"
},
{
"width": 600,
"url": "images/2016/01/01/nytnow/the-week-on-instagram-slide-8Y3Z/the-week-on-instagram-slide-8Y3Z-articleLarge.jpg",
"height": 600,
"subtype": "xlarge",
"legacy": {
"xlargewidth": "600",
"xlarge": "images/2016/01/01/nytnow/the-week-on-instagram-slide-8Y3Z/the-week-on-instagram-slide-8Y3Z-articleLarge.jpg",
"xlargeheight": "600"
},
"type": "image"
},
{
"width": 75,
"url": "images/2016/01/01/nytnow/the-week-on-instagram-slide-8Y3Z/the-week-on-instagram-slide-8Y3Z-thumbStandard.jpg",
"height": 75,
"subtype": "thumbnail",
"legacy": {
"thumbnailheight": "75",
"thumbnail": "images/2016/01/01/nytnow/the-week-on-instagram-slide-8Y3Z/the-week-on-instagram-slide-8Y3Z-thumbStandard.jpg",
"thumbnailwidth": "75"
},
"type": "image"
}
],
"headline": {
"main": "The Week on Instagram"
},
"keywords": [],
"pub_date": "2016-01-01T00:00:00Z",
"document_type": "multimedia",
"news_desk": "NYT Now",
"section_name": "NYT Now",
"subsection_name": null,
"byline": [],
"type_of_material": "Slideshow",
"_id": "5687cefb38f0d82225327003",
"word_count": "24",
"slideshow_credits": "Ben C. Solomon/The New York Times"
},
{
"web_url": "https://wordplay.blogs.nytimes.com/2016/01/01/mass-master/",
"snippet": "David Phillips provides our first Saturday challenge of 2016....",
"lead_paragraph": null,
"abstract": "David Phillips provides our first Saturday challenge of 2016.",
"print_page": null,
"blog": [],
"source": "The New York Times",
"multimedia": [{
"width": 190,
"url": "images/2016/01/01/crosswords/0101yalejpg/0101yalejpg-thumbWide.jpg",
"height": 126,
"subtype": "wide",
"legacy": {
"wide": "images/2016/01/01/crosswords/0101yalejpg/0101yalejpg-thumbWide.jpg",
"wideheight": "126",
"widewidth": "190"
},
"type": "image"
},
{
"width": 600,
"url": "images/2016/01/01/crosswords/0101yalejpg/0101yalejpg-articleLarge.jpg",
"height": 400,
"subtype": "xlarge",
"legacy": {
"xlargewidth": "600",
"xlarge": "images/2016/01/01/crosswords/0101yalejpg/0101yalejpg-articleLarge.jpg",
"xlargeheight": "400"
},
"type": "image"
},
{
"width": 75,
"url": "images/2016/01/01/crosswords/0101yalejpg/0101yalejpg-thumbStandard.jpg",
"height": 75,
"subtype": "thumbnail",
"legacy": {
"thumbnailheight": "75",
"thumbnail": "images/2016/01/01/crosswords/0101yalejpg/0101yalejpg-thumbStandard.jpg",
"thumbnailwidth": "75"
},
"type": "image"
}
],
"headline": {
"main": "Mass Master",
"kicker": "Wordplay"
},
"keywords": [{
"rank": "1",
"name": "subject",
"value": "Crossword Puzzles"
}],
"pub_date": "2016-01-01T22:00:56Z",
"document_type": "blogpost",
"news_desk": "Business",
"section_name": "Crosswords & Games",
"subsection_name": null,
"byline": {
"person": [{
"organization": "",
"role": "reported",
"firstname": "Deb",
"rank": 1,
"lastname": "AMLEN"
}],
"original": "By DEB AMLEN"
},
"type_of_material": "Blog",
"_id": "56873d8d38f0d82225326f90",
"word_count": "618",
"slideshow_credits": null
},
{
"web_url": "https://krugman.blogs.nytimes.com/2016/01/01/friday-night-music-more-wild-reeds/",
"snippet": "Harmony to soothe the soul....",
"lead_paragraph": null,
"abstract": "Harmony to soothe the soul.",
"print_page": null,
"blog": [],
"source": "The New York Times",
"multimedia": [],
"headline": {
"main": "Friday Night Music: More Wild Reeds",
"kicker": "Paul Krugman"
},
"keywords": [],
"pub_date": "2016-01-01T21:17:09Z",
"document_type": "blogpost",
"news_desk": "OpEd",
"section_name": "Opinion",
"subsection_name": null,
"byline": {
"person": [{
"organization": "",
"role": "reported",
"firstname": "Paul",
"rank": 1,
"lastname": "KRUGMAN"
}],
"original": "By PAUL KRUGMAN"
},
"type_of_material": "Blog",
"_id": "5687337938f0d82225326f8b",
"word_count": "13",
"slideshow_credits": null
}
]
}
}
我试图使用[JsonArray(AllowNullItems = true)]
属性来装饰有问题的类,但无济于事。唯一没有例外的是当我将显式声明为类对象的变量更改为object
时,但这并不完全理想。
非常感谢任何帮助。我似乎无法让这种反序列化工作。
对json进行反序列化的调用。
public void GetThisMonthsArticles()
{
string endpoint = string.Format(Endpoint, new object[] { DateTime.Now.Year, DateTime.Now.Month, Resources.APIKeys.NYTimesAPI });
HttpClient client = HttpPersistentClient.GetHttpClient(endpoint);
WebClient wc = new WebClient();
string json = wc.DownloadString(endpoint);
RootObject = JsonConvert.DeserializeObject<RootObject>(json);
}
答案 0 :(得分:0)
也许你在班上犯了一些错误。
您可以尝试使用此工具:https://jsonutils.com/
它将为您生成所有课程。请记住在下拉列表中选择JsonProperty。
然后你可以使用:
var object = JsonConvert.DeserializeObject<RootObject>(json);
最后,您可以通过对象的LINQ查询访问您的数据,以获得您所需的数据。 我希望它对你有用。