簡體   English   中英

無法反序列化嵌套 JSON 列表中的數據

[英]Unable to Deserialize data from Nested JSON List

在了解了 C# 類 Constructors 和 ArrayLists 之后來到這里,以免在這里提出一個完全愚蠢的問題:)

我正在嘗試在從 API GET 調用返回的 JSON 的嵌套列表下面反序列化,如下所示:

我已經能夠從empArra (字段: Emp )中獲取值,但后續列表(如yearArrayprodsale )並沒有返回那里的值。

你能看看下面的代碼哪里做錯了嗎?

JSON

 [
    {
        "employee":"156718100",
        "availability":[
            {
                "year":2018,
                "sales":{
                    "availability":"Maybe",
                    "reason":""
                },
                "prod":{
                    "availability":"Maybe",
                    "reason":""
                }
            },
            {
                "year":2019,
                "sales":{
                    "availability":"Maybe",
                    "reason":""
                },
                "prod":{
                    "availability":"Maybe",
                    "reason":""
                }
            },
            {
                "year":2020,
                "sales":{
                    "availability":"Maybe",
                    "reason":""
                },
                "top":{
                    "availability":"Maybe",
                    "reason":""
                }
            },
            {
                "year":2021,
                "sales":{
                    "availability":"Maybe",
                    "reason":""
                },
                "prod":{
                    "availability":"Maybe",
                    "reason":""
                }
            }
        ]
    }
]

課程

public class sale
{
    public string SaleAvailability { get; set; }
    public string SaleReason { get; set; }
    
    public sale(string pSaleAvailability, string pSaleReason)
    {
        this.SaleAvailability = pSaleAvailability;
        this.SaleReason = pSaleReason;
    }
    
    public override string ToString()
    {
        return string.Format("{0} {1}", SaleAvailability, SaleReason);
    }
}

public class prod
{
    public string ProdAvailability { get; set; }
    public string ProdReason { get; set; }
    
    public prod(string pProdAvailability, string pProdReason)
    {
        this.ProdAvailability = pProdAvailability;
        this.ProdReason = pProdReason;
    }
    
    public override string ToString()
    {
        return string.Format("{0} {1}", ProdAvailability, ProdReason);
    }
}

public class yearArray
{
    public int Year { get; set; }

    public yearArray(int pYear)
    {
        this.Year = pYear;
    }

    List<sale> Sale { get; set; } = new List<sale>();
    List<prod> Prod { get; set; } = new List<prod>();
}

public class rootAvailability
{
    public List<yearArray> YearArray { get; set; } = new List<yearArray>();
}

public class empArray
{
    public string Emp { get; set; }
    public List<rootAvailability> RootAvailability { get; set; } = new List<rootAvailability>();
}

public class rootArray
{
    public List<empArray> EmpArrays { get; set; } = new List<empArray>();

}

main()方法

(從 API 獲得響應后)

IRestResponse response = client.Execute<rootArray>(request);
    
//Console.WriteLine(response.Content);

List<rootArray> rootArrays = JsonConvert.DeserializeObject<List<rootArray>>(response.Content);

List<empArray> empArrays = JsonConvert.DeserializeObject<List<empArray>>(response.Content);

List<rootAvailability> rootAvailabilities = JsonConvert.DeserializeObject<List<rootAvailability>>(response.Content);

List<yearArray> yearArrays = JsonConvert.DeserializeObject<List<yearArray>>(response.Content);

List<sale> clsSale = JsonConvert.DeserializeObject<List<sale>>(response.Content);

List<prod> clsProd = JsonConvert.DeserializeObject<List<prod>>(response.Content);


foreach (var rootitem in rootArrays)
{
    foreach (var emparrayitem in empArrays)
    {
        Console.WriteLine("NSN: " + emparrayitem.Emp);
        
        foreach (var rootavailabbilitiesitem in rootAvailabilities)
        {
            
            foreach (var yearArrayItem in yearArrays)
            {
                
                Console.WriteLine("Year: " + yearArrayItem.Year);

                foreach (var saleItem in clsSale)
                {

                    Console.WriteLine("SaleAvailability: " + saleItem.SaleAvailability);
                    Console.WriteLine("SaleReason: " + saleItem.SaleReason);
                }
                foreach (var prodItem in clsProd)
                {

                    Console.WriteLine("SaleAvailability: " + prodItem.ProdAvailability);
                    Console.WriteLine("SaleReason: " + prodItem.ProdReason);
                }
            }
        }
    }
}

結果

Emp: 159252663
Year: 0
SaleAvailability:
SaleReason:
SaleAvailability:
SaleReason:

您的方法有兩個問題:

  1. 您想為不同的 class 實例反復反序列化相同的源 ( response.Content )。 它可以反序列化為一種 object 類型:您的頂級實體。
  1. 您的數據 model 不反映您的數據。 例如YearArray應該有一個ProdSale屬性,而不是它們的列表。

你有幾個選擇如何解決它。 給大家分享兩個最常見的:

用正確的命名

您的 object model 應如下所示:

public class Sale
{
    public string Availability { get; set; }
    public string Reason { get; set; }
}

public class Prod
{
    public string Availability { get; set; }
    public string Reason { get; set; }
}

public class MidLevel
{
    public int Year { get; set; }
    public Sale Sales { get; set; }
    public Prod Top { get; set; }
}

public class TopLevel
{
    public string Employee { get; set; }
    public List<MidLevel> Availability { get; set; } = new List<MidLevel>();
}

然后您需要做的就是調用以下命令:

var result = JsonConvert.DeserializeObject<TopLevel[]>(json);

現在,您的結果將填充所有數據。

使用JsonProperty

如果您不想在您的域 model 中使用相同的名稱(在 json 中使用),那么您可以通過JsonProperty屬性定義這兩個世界之間的映射。

現在您的域 model 可以如下所示:

public class SalesInformation
{
    [JsonProperty(PropertyName = "availability")]
    public string Avail { get; set; }
    [JsonProperty(PropertyName = "reason")]
    public string Reasoning { get; set; }
}

public class ProdInformation
{
    [JsonProperty(PropertyName = "availability")]
    public string Availability { get; set; }
    [JsonProperty(PropertyName = "reason")]
    public string Reasoning { get; set; }
}

public class MidLevel
{
    [JsonProperty(PropertyName = "year")]
    public int AvailYear { get; set; }
    [JsonProperty(PropertyName = "sales")]
    public SalesInformation SalesInfos { get; set; }
    [JsonProperty(PropertyName = "top")]
    public ProdInformation ProdInfos { get; set; }
}

public class TopLevel
{
    [JsonProperty(PropertyName = "employee")]
    public string Emp { get; set; }
    [JsonProperty(PropertyName = "availability")]
    public List<MidLevel> Availabilities { get; set; } = new List<MidLevel>();
}

用法將完全相同:

var result = JsonConvert.DeserializeObject<TopLevel[]>(json);

更新:如何顯示數據

在控制台應用程序中表示層次結構可以通過多種方式實現。 這里我將使用縮進。 我介紹了以下微小的輔助方法:

public static void WriteWithIndent(int level, string message) => Console.WriteLine("".PadLeft(level * 2) + message);

有了這個,數據可視化可以通過以下方式實現:

var result = JsonConvert.DeserializeObject<TopLevel[]>(json);
foreach (var topLevel in result)
{
    Console.WriteLine($"Employee: {topLevel.Emp}");
    foreach (var midLevel in topLevel.Availabilities)
    {
        WriteWithIndent(1, $"Year: {midLevel.AvailYear}");
        WriteWithIndent(1, "Sales:");
        WriteWithIndent(2, $"Avail: {midLevel.SalesInfos.Avail}");
        WriteWithIndent(2, $"Reason: {midLevel.SalesInfos.Reasoning}");
        WriteWithIndent(1, "Top:");
        WriteWithIndent(2, $"Avail: {midLevel.ProdInfos.Avail}");
        WriteWithIndent(2, $"Reason: {midLevel.ProdInfos.Reasoning}");
    }
}

打印的 output 將如下所示:

Employee: 156718100
  Year: 2018
  Sales:
    Avail: Maybe
    Reason:
  Top:
    Avail: Maybe
    Reason:
  Year: 2019
  Sales:
    Avail: Maybe
    Reason:
  Top:
    Avail: Maybe
    Reason:
  Year: 2020
  Sales:
    Avail: Maybe
    Reason:
  Top:
    Avail: Maybe
    Reason:
  Year: 2021
  Sales:
    Avail: Maybe
    Reason:
  Top:
    Avail: Maybe
    Reason:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM