c# - 反序列化 JSON 数组与列表
问题描述
所以我正在使用这个 myMarketNews api:https ://mymarketnews.ams.usda.gov/mars-api/getting-started
我可以使用以下代码自己提取报告列表:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using RestSharp;
using RestSharp.Authenticators;
namespace MarketNewsJson
{
internal static class MarketNewsJson
{
private static void Main(string[] args)
{
var client = new RestClient("https://marsapi.ams.usda.gov")
{
Authenticator = new HttpBasicAuthenticator("mars_test_343343", "")
};
var request = new RestRequest("services/v1.1/reports", DataFormat.Json);
var response = client.Get(request);
var reports = JsonConvert.DeserializeObject<List<Report>>(response.Content);
foreach (var report in reports)
{
Console.WriteLine($"{report.SlugId} {report.SlugName} - {report.ReportTitle}");
}
}
}
public class Report
{
[JsonProperty("slug_id")]
public string SlugId { get; set; }
[JsonProperty("slug_name")]
public string SlugName { get; set; }
[JsonProperty("report_title")]
public string ReportTitle { get; set; }
[JsonProperty("published_date")]
public string PublishedDate { get; set; }
[JsonProperty("markets")]
public List<string> Markets { get; set; }
[JsonProperty("market_types")]
public List<string> MarketTypes { get; set; }
[JsonProperty("offices")]
public List<string> Offices { get; set; }
[JsonProperty("sectionNames")]
public List<string> SectionNames { get; set; }
}
}
这将提取报告名称及其其他属性。但是,我也希望能够自己提取单个报告的 JSON 信息。我注意到在“排序”选项卡中,它显示了单个报告的属性,并且对于指定单个报告,它类似于 var request = new RestRequest("services/v1.1/reports/1095", DataFormat.Json ); 报告 1095 本身,而不是所有报告的 /reports。当我这样做时,我收到反序列化错误:
Newtonsoft.Json.JsonSerializationException:'无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.List`1[MarketNewsJson.Report]',因为该类型需要 JSON 数组(例如 [1,2,3])正确反序列化。
这是因为单个报告的 JSON 格式与报告列表本身的格式不同吗?如果是这样,我是否需要一个新行来为单个报告反序列化它,而当我想获取单个报告及其属性时,只需将另一行注释掉?
编辑:JSON响应
这就是我当前仅提取报告名称、ID 和标题(工作正常)的 JSON 响应的样子:
[
{
"slug_id": "1034",
"slug_name": "MD_DA105",
"report_title": "Whey - Western & Eastern Europe Report",
"published_date": "07/30/2020 08:25:01",
"markets": ["N/A"],
"market_types": ["Point of Sale"],
"offices": ["Madison"],
"sectionNames": []
}, {
"slug_id": "1035",
"slug_name": "MD_DA106",
"report_title": "Skim Milk Powder - Europe",
"published_date": "07/30/2020 08:25:01",
"markets": ["N/A"],
"market_types": ["Point of Sale"],
"offices": ["Madison"],
"sectionNames": []
}
]
从文档中可以看出,报告的各个数据应该是这样的:
{
"results": [
{
"report_begin_date": "2018-01-08",
"report_end_date": "2018-01-08",
"published_date": "2018-01-31",
"office_name": "Madison",
"office_code": "DA-MD",
"office_city": "Madison",
"office_state": "WI",
"market_location_name": "National Cold Storage",
"market_location_city": "",
"market_location_state": "WI",
"group": null,
"category": "Hard Products",
"commodity": "Cheese",
"market_type": "Cold Storage",
"market_type_category": "Dairy Market",
"slug_id": "1095",
"slug_name": "MD_DA953",
"community": "Dairy",
"quality": "N/A",
"holdings_unit": "LBS",
"holdings_current_lbs": "96009227",
"holdings_1stDayMTH_lbs": "96245049",
"holdings_change_lbs": "-235822",
"holdings_change_percent": "0.0000",
"currentMTH_1stDay": "2018-01-01",
"report_narrative": null,
"commodity_narrative": null,
"special_announcement": null
}
解决方案
您将不得不使用两个不同的课程。一个用于列表,另一个用于 ReportObject。
对于services/v1.1/reports
,您将需要使用帖子中已有的课程。但是对于您获得的报告services/v1.1/reports/1095
,您将需要使用不同的类来反序列化您的响应。这主要是因为您得到的响应与没有 ID 时得到的报告大多不同。
public class ReportResultResponse {
// This is a List of objects even though it might always be a single element in the json
[JsonProperty("results")]
public List<ReportResultForID> Results {get;set;}
}
public class ReportResultForID {
[JsonProperty("report_begin_date")]
public DateTime ReportBeginDate {get;set;}
[JsonProperty("report_end_date")]
public DateTime ReportEndDate {get;set;}
...
[JsonProperty("slug_name")]
public string SlugName {get;set;}
...
}
// Then for the reports you get with ID, you would deserialize like this,
var request = new RestRequest("services/v1.1/reports/1095", DataFormat.Json);
var response = client.Get(request);
var reports = JsonConvert.DeserializeObject<ReportResultResponse>(response.Content);
推荐阅读
- sql-server - 在 SQL Server 中使用 EncryptByPassword 时保护密码
- c - 从C中的整数中提取一个字节
- android - 我的设备语言处于 ltr 更改中,我想将我的应用程序的语言更改为 rtl 以用于 android 中的阿拉伯语
- java - 即时从 .tgz 文件夹中读取文件
- jenkins - 如何从 JobDSL 调用 Jenkinsfile 管道步骤?
- angular - 角http响应中的大整数(长)被四舍五入
- html - 中心孩子到其父母的中心
- gitlab - Gitlab CI Shell Runner 返回 500 错误
- go - 向 exec.Cmd.StdinPipe() 写入超过 4K 字节
- elasticsearch - 对象而不是关键字的桶聚合