如何正确反序列化并从 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 获取值的主要内容,如果未能解决你的问题,请参考以下文章

使用JSON.Net将字符串属性值反序列化为类实例

Jackson 使用枚举键、POJO 值反序列化为 Map

根据字段值反序列化为密封子类

Jackson MismatchedInputException(没有从字符串值反序列化的字符串参数构造函数/工厂方法)

使用变量名数组反序列化 JSON

C# JSON 反序列化:如何从 JSON 对象数组中获取值 [重复]