如何正确反序列化并从 JSON 获取值
Posted
技术标签:
【中文标题】如何正确反序列化并从 JSON 获取值【英文标题】:How correctly deserialize and obtain values from JSON 【发布时间】:2020-05-09 07:14:36 【问题描述】:我的 json:
[
"id": "SUPER_TOTAL",
"title": "All",
"ticketSales": [
"dateStart": null,
"dateFinish": null,
"sum": 0,
"quantity": 0,
"sessions": 0,
"rupart": 0,
"moneyPerSession": 0,
"ticketsPerSession": 0,
"middlePrice": 0,
"periodId": "SUPER_TOTAL"
,
"dateStart": null,
"dateFinish": null,
"sum": 15355230,
"quantity": 88943,
"sessions": 13171,
"rupart": 0,
"moneyPerSession": 1165.84,
"ticketsPerSession": 7,
"middlePrice": 172.64,
"periodId": "TOTAL"
,
"dateStart": "2020.01.22T00:00:00",
"dateFinish": "2020.01.23T00:00:00",
"sum": 15355230,
"quantity": 88943,
"sessions": 13171,
"rupart": 65.5,
"moneyPerSession": 1165.84,
"ticketsPerSession": 7,
"middlePrice": 172.64,
"periodId": "20200122"
]
,
"id": "TOTAL",
"title": "Regions",
"ticketSales": [
"dateStart": null,
"dateFinish": null,
"sum": 0,
"quantity": 0,
"sessions": 0,
"rupart": 0,
"moneyPerSession": 0,
"ticketsPerSession": 0,
"middlePrice": 0,
"periodId": "SUPER_TOTAL"
,
"dateStart": null,
"dateFinish": null,
"sum": 199057,
"quantity": 1361,
"sessions": 196,
"rupart": 0,
"moneyPerSession": 1015.6,
"ticketsPerSession": 7,
"middlePrice": 146.26,
"periodId": "TOTAL"
,
"dateStart": "2020.01.22T00:00:00",
"dateFinish": "2020.01.23T00:00:00",
"sum": 199057,
"quantity": 1361,
"sessions": 196,
"rupart": 58.2,
"moneyPerSession": 1015.6,
"ticketsPerSession": 7,
"middlePrice": 146.26,
"periodId": "20200122"
]
,
"id": "2400000100000",
"title": "City",
"ticketSales": [
"dateStart": null,
"dateFinish": null,
"sum": 0,
"quantity": 0,
"sessions": 0,
"rupart": 0,
"moneyPerSession": 0,
"ticketsPerSession": 0,
"middlePrice": 0,
"periodId": "SUPER_TOTAL"
,
"dateStart": null,
"dateFinish": null,
"sum": 199057,
"quantity": 1361,
"sessions": 196,
"rupart": 0,
"moneyPerSession": 1015.6,
"ticketsPerSession": 7,
"middlePrice": 146.26,
"periodId": "TOTAL"
,
"dateStart": "2020.01.22T00:00:00",
"dateFinish": "2020.01.23T00:00:00",
"sum": 199057,
"quantity": 1361,
"sessions": 196,
"rupart": 58.2,
"moneyPerSession": 1015.6,
"ticketsPerSession": 7,
"middlePrice": 146.26,
"periodId": "20200122"
]
]
生成的类:
public class TicketSale
public string dateStart get; set;
public string dateFinish get; set;
public int sum get; set;
public int quantity get; set;
public int sessions get; set;
public double rupart get; set;
public double moneyPerSession get; set;
public int ticketsPerSession get; set;
public double middlePrice get; set;
public string periodId get; set;
public class RootObject
public string id get; set;
public string title get; set;
public List<TicketSale> ticketSales get; set;
我需要从每个ticketSales 中获取总和、数量、会话的值,但只在数组中的第二个和第三个对象中,而不是第一个,因为他总是有零值。所以 TicketSale 类将是:
public class TicketSale
public int sum get; set;
public int quantity get; set;
public int sessions get; set;
所以它将是 2 x 3 = 6 个带有值的 TicketSales 类。我正在使用 Newtonsoft.Json。
【问题讨论】:
那么你的问题是什么?你试过什么?您在访问所需数据时遇到了什么问题?查看How to Ask 并包含minimal reproducible example,显示您获取值的尝试。 【参考方案1】:我需要从每个ticketSales 中获取总和、数量、会话的值,但只在数组中的第二个和第三个对象中,而不是第一个
如果您需要 TicketSales 而不是第一个元素,您可以使用带有 Skip(1) 语句的 Linq 查询来完成。
回答您正在寻找的答案
var main = JsonConvert.DeserializeObject<List<RootObject>>(json);
var ticketSales = main.Select(x => x.ticketSales.Skip(1)).ToList();
main 是转换后的完整 json 文档,ticketSales 是数组中每个元素的所有 ticketSales 的数组。如果您想要一个列表(而不是三个)中的所有 ticketSales 集合,您可以使用 SelectMany
var ticketSales = main.Select(x => x.ticketSales.Skip(1)).SelectMany(x => x).ToList();
SelectMany 会将所有ticketSales 放在一个List 中。
此外
如果您对包含所有 TicketSales 总和的 1 个 TicketSale 项目感兴趣,您可以根据上面的 ticketSales 变量创建一个新对象。
TicketSale allSalesCollective = new TicketSale()
sum = ticketSales.Sum(x => x.sum),
quantity = ticketSales.Sum(x => x.quantity),
sessions = ticketSales.Sum(x => x.sessions)
;
这将为您提供 TicketSale 的总和、数量和会话。
【讨论】:
【参考方案2】:所以,请使用 Json.Net。这是最简单的方法。 https://www.newtonsoft.com/json/help/html/DeserializeObject.htm
示例如下:
var json = "[\r\n \r\n \"id\": \"SUPER_TOTAL\",\r\n \"title\": \"All\",\r\n \"ticketSales\": [\r\n \r\n \"dateStart\": null,\r\n \"dateFinish\": null,\r\n \"sum\": 0,\r\n \"quantity\": 0,\r\n \"sessions\": 0,\r\n \"rupart\": 0,\r\n \"moneyPerSession\": 0,\r\n \"ticketsPerSession\": 0,\r\n \"middlePrice\": 0,\r\n \"periodId\": \"SUPER_TOTAL\"\r\n ,\r\n \r\n \"dateStart\": null,\r\n \"dateFinish\": null,\r\n \"sum\": 15355230,\r\n \"quantity\": 88943,\r\n \"sessions\": 13171,\r\n \"rupart\": 0,\r\n \"moneyPerSession\": 1165.84,\r\n \"ticketsPerSession\": 7,\r\n \"middlePrice\": 172.64,\r\n \"periodId\": \"TOTAL\"\r\n ,\r\n \r\n \"dateStart\": \"2020.01.22T00:00:00\",\r\n \"dateFinish\": \"2020.01.23T00:00:00\",\r\n \"sum\": 15355230,\r\n \"quantity\": 88943,\r\n \"sessions\": 13171,\r\n \"rupart\": 65.5,\r\n \"moneyPerSession\": 1165.84,\r\n \"ticketsPerSession\": 7,\r\n \"middlePrice\": 172.64,\r\n \"periodId\": \"20200122\"\r\n \r\n ]\r\n ,\r\n \r\n \"id\": \"TOTAL\",\r\n \"title\": \"Regions\",\r\n \"ticketSales\": [\r\n \r\n \"dateStart\": null,\r\n \"dateFinish\": null,\r\n \"sum\": 0,\r\n \"quantity\": 0,\r\n \"sessions\": 0,\r\n \"rupart\": 0,\r\n \"moneyPerSession\": 0,\r\n \"ticketsPerSession\": 0,\r\n \"middlePrice\": 0,\r\n \"periodId\": \"SUPER_TOTAL\"\r\n ,\r\n \r\n \"dateStart\": null,\r\n \"dateFinish\": null,\r\n \"sum\": 199057,\r\n \"quantity\": 1361,\r\n \"sessions\": 196,\r\n \"rupart\": 0,\r\n \"moneyPerSession\": 1015.6,\r\n \"ticketsPerSession\": 7,\r\n \"middlePrice\": 146.26,\r\n \"periodId\": \"TOTAL\"\r\n ,\r\n \r\n \"dateStart\": \"2020.01.22T00:00:00\",\r\n \"dateFinish\": \"2020.01.23T00:00:00\",\r\n \"sum\": 199057,\r\n \"quantity\": 1361,\r\n \"sessions\": 196,\r\n \"rupart\": 58.2,\r\n \"moneyPerSession\": 1015.6,\r\n \"ticketsPerSession\": 7,\r\n \"middlePrice\": 146.26,\r\n \"periodId\": \"20200122\"\r\n \r\n ]\r\n ,\r\n \r\n \"id\": \"2400000100000\",\r\n \"title\": \"City\",\r\n \"ticketSales\": [\r\n \r\n \"dateStart\": null,\r\n \"dateFinish\": null,\r\n \"sum\": 0,\r\n \"quantity\": 0,\r\n \"sessions\": 0,\r\n \"rupart\": 0,\r\n \"moneyPerSession\": 0,\r\n \"ticketsPerSession\": 0,\r\n \"middlePrice\": 0,\r\n \"periodId\": \"SUPER_TOTAL\"\r\n ,\r\n \r\n \"dateStart\": null,\r\n \"dateFinish\": null,\r\n \"sum\": 199057,\r\n \"quantity\": 1361,\r\n \"sessions\": 196,\r\n \"rupart\": 0,\r\n \"moneyPerSession\": 1015.6,\r\n \"ticketsPerSession\": 7,\r\n \"middlePrice\": 146.26,\r\n \"periodId\": \"TOTAL\"\r\n ,\r\n \r\n \"dateStart\": \"2020.01.22T00:00:00\",\r\n \"dateFinish\": \"2020.01.23T00:00:00\",\r\n \"sum\": 199057,\r\n \"quantity\": 1361,\r\n \"sessions\": 196,\r\n \"rupart\": 58.2,\r\n \"moneyPerSession\": 1015.6,\r\n \"ticketsPerSession\": 7,\r\n \"middlePrice\": 146.26,\r\n \"periodId\": \"20200122\"\r\n \r\n ]\r\n \r\n]";
RootObject[] root = JsonConvert.DeserializeObject<RootObject[]>(json);
foreach(var rootItem in root)
rootItem.ticketSales.RemoveAt(0);
"json" 是带有 json 字符串的变量
要删除第一个项目,您可以使用 RemoveAt(0)
【讨论】:
我开始回答后,问题变了。首先是关于如何反序列化它。 @TemaTre 不正确。自发布以来,问题没有改变;它甚至没有一次编辑。 @TemaTre 答案也正确。感谢您的帮助!以上是关于如何正确反序列化并从 JSON 获取值的主要内容,如果未能解决你的问题,请参考以下文章
Jackson MismatchedInputException(没有从字符串值反序列化的字符串参数构造函数/工厂方法)