C#.Net3.5下构建含嵌套List的JSON payload实现问题求助
问题背景
构建Article资源对应的JSON payload时,Postman可正常完成CRUD请求,但C#实现时UomUnitPrices嵌套字段构造失败。
当前开发环境约束:
- .Net 3.5
- RestSharp 105.2.3.0
- Newtonsoft.Json 13.0.0.0
可正常序列化的单嵌套结构示例:
{ "Id": "10006", "Barcodes": [ { "Barcode": "1010006" } ], "UomUnitPrices": [ { "Prices": [ { "PriceLevelId": "1", "PriceValue": 5.000 } ] } ] }
需要构造的目标payload结构如下:
{ "Id": "10006", "Barcodes": [ { "Barcode": "1010006" } ], "UomUnitPrices": [ { "Prices": [ { "PriceLevelId": "1", "PriceValue": 5.000 }, { "PriceLevelId": "100", "PriceValue": 20.000 }, { "PriceLevelId": "200", "PriceValue": 10.000 }, { "PriceLevelId": "300", "PriceValue": 15.000 }, { "PriceLevelId": "400", "PriceValue": 17.500 } ] } ], "Description": "Article Description", "GroupAId": "50", "VisibilityCriteriaId": "1", "IsValid": true, "MeasureUnitId": "pcs", "Vat1Id": "1", "Vat2Id": "2" }
当前除嵌套Prices列表的UomUnitPrices字段外,其余字段构造均正常,已定义的DTO类代码如下:
public partial class ArticlesDTO { ... [JsonProperty("UomUnitPrices")] public List<UomUnitPrice> UomUnitPrices { get; set; } ... } public partial class UomUnitPrice { [JsonProperty("Prices")] public IList<Price> Prices { get; set; } } public partial class Price { [JsonProperty("PriceLevelId")] public string PriceLevelId { get; set; } [JsonProperty("PriceValue")] public double PriceValue { get; set; } } public partial class ArticlesDTO { public ArticlesDTO CreateArticle(string id, string description, string groupAid, bool isValid, string measureUnitId, string vat1Id, string vat2Id) { Barcode barcode = new Barcode().CreateBarcode("String Barcode"); UomUnitPrice uomUnitPrice = new UomUnitPrice().UomUnitPriceList(); //此处逻辑缺失 ArticlesDTO article = new ArticlesDTO() { Id = id, Description = description, GroupAId = groupAid, VisibilityCriteriaId = 1, IsValid = true, MeasureUnitId = measureUnitId, Vat1Id = vat1Id, Vat2Id = vat2Id, Barcodes = new List<Barcode>() { barcode }, UomUnitPrices = new List<UomUnitPrice>() { uomUnitPrice } }; return article; } public ArticlesDTO CreateArticle(DataRow dataRow)... }
卡点为不知道如何初始化UomUnitPrice实例并为Prices属性赋值多个Price对象,后续还需要基于System.Data.DataRow构造对应payload。
实现方案
不需要额外封装UomUnitPriceList()方法,.NET 3.5原生支持对象、集合初始化器语法,直接按嵌套层级逐层赋值即可,修改后的CreateArticle方法代码如下:
public ArticlesDTO CreateArticle(string id, string description, string groupAid, bool isValid, string measureUnitId, string vat1Id, string vat2Id) { Barcode barcode = new Barcode().CreateBarcode("1010006"); // 初始化UomUnitPrice实例,直接为Prices属性赋值多个Price对象 UomUnitPrice uomUnitPrice = new UomUnitPrice() { Prices = new List<Price>() { new Price(){ PriceLevelId = "1", PriceValue = 5.000d }, new Price(){ PriceLevelId = "100", PriceValue = 20.000d }, new Price(){ PriceLevelId = "200", PriceValue = 10.000d }, new Price(){ PriceLevelId = "300", PriceValue = 15.000d }, new Price(){ PriceLevelId = "400", PriceValue = 17.500d } } }; ArticlesDTO article = new ArticlesDTO() { Id = id, Description = description, GroupAId = groupAid, // 注意:原代码此处赋值int类型1,与DTO的string类型定义不匹配,会导致序列化格式错误,需改为字符串 VisibilityCriteriaId = "1", IsValid = isValid, MeasureUnitId = measureUnitId, Vat1Id = vat1Id, Vat2Id = vat2Id, Barcodes = new List<Barcode>() { barcode }, UomUnitPrices = new List<UomUnitPrice>() { uomUnitPrice } }; return article; }
基于DataRow构造时,只需要循环读取行内价格数据,往Prices集合中Add对应Price实例即可,示例逻辑:
public ArticlesDTO CreateArticle(DataRow dataRow) { Barcode barcode = new Barcode().CreateBarcode(dataRow["Barcode"].ToString()); UomUnitPrice uomUnitPrice = new UomUnitPrice(); uomUnitPrice.Prices = new List<Price>(); // 按实际DataRow的列名读取价格数据,逐行添加到Prices集合 uomUnitPrice.Prices.Add(new Price(){ PriceLevelId = dataRow["PriceLevel1Id"].ToString(), PriceValue = Convert.ToDouble(dataRow["Price1Value"]) }); uomUnitPrice.Prices.Add(new Price(){ PriceLevelId = dataRow["PriceLevel100Id"].ToString(), PriceValue = Convert.ToDouble(dataRow["Price100Value"]) }); // 其余价格项按相同逻辑添加即可 ArticlesDTO article = new ArticlesDTO() { Id = dataRow["Id"].ToString(), Description = dataRow["Description"].ToString(), GroupAId = dataRow["GroupAId"].ToString(), VisibilityCriteriaId = dataRow["VisibilityCriteriaId"].ToString(), IsValid = Convert.ToBoolean(dataRow["IsValid"]), MeasureUnitId = dataRow["MeasureUnitId"].ToString(), Vat1Id = dataRow["Vat1Id"].ToString(), Vat2Id = dataRow["Vat2Id"].ToString(), Barcodes = new List<Barcode>() { barcode }, UomUnitPrices = new List<UomUnitPrice>() { uomUnitPrice } }; return article; }
构造完成后直接调用JsonConvert.SerializeObject(article)即可生成和Postman请求完全一致的JSON payload,不需要额外做格式转换。
内容的提问来源于stack exchange,提问作者Stefan Fitsch
相关产品推荐
相关产品推荐

