[英]Unable to Deserialize data from Nested JSON List
在了解了 C# 类 Constructors 和 ArrayLists 之后来到这里,以免在这里提出一个完全愚蠢的问题:)
我正在尝试在从 API GET 调用返回的 JSON 的嵌套列表下面反序列化,如下所示:
我已经能够从empArra
(字段: Emp
)中获取值,但后续列表(如yearArray
、 prod
和sale
)并没有返回那里的值。
你能看看下面的代码哪里做错了吗?
[
{
"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:
您的方法有两个问题:
response.Content
)。 它可以反序列化为一种 object 类型:您的顶级实体。YearArray
应该有一个Prod
和Sale
属性,而不是它们的列表。你有几个选择如何解决它。 给大家分享两个最常见的:
您的 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.