У меня есть проблема, когда мне нужно взять любой объект и сгладить его в формате пары ключ-значение
Это действительно хорошо работает для простых классов и даже классов, в которых у меня есть другие классы
Глядя на пример,
public class Buyer
{
[JsonProperty("name")]public string Name { get; set; }
[JsonProperty("address")]public string Address { get; set; }
[JsonProperty("lastPurchase")]public Purchase LastPurchase { get; set; }
public Buyer()
{
Name = "Joe Bloggs";
Address = "An adddress somewhere";
AllPurchases = new List<Purchase>()
{
new Purchase() {PurchaseAmount = 100, PurchaseDateTime = Convert.ToDateTime("2017-01-01")},
new Purchase() {PurchaseAmount = 100, PurchaseDateTime = Convert.ToDateTime("2018-01-01")}
};
LastPurchase = new Purchase() {PurchaseAmount = 100, PurchaseDateTime = Convert.ToDateTime("2018-01-01")};
}
[JsonIgnore]
public List<Purchase> AllPurchases { get; set; }
}
public class Purchase
{
public DateTime PurchaseDateTime { get; set; }
public double PurchaseAmount { get; set; }
}
У меня есть код ниже, который является моей текущей реализацией
var buyer = new Buyer();
var json = JsonConvert.SerializeObject(buyer);
var obj = JObject.Parse(json);
var result = obj.Descendants()
.OfType<JProperty>()
.Where(s => s.Value.Type != JTokenType.Object)
.Select(p => new KeyValuePair<string, string>(p.Path,
p.Value.Type == JTokenType.Array || p.Value.Type == JTokenType.Object
? null : p.Value.ToString()));
var serializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ContractResolver = new CamelCasePropertyNamesContractResolver(),
};
var newJson = JsonConvert.SerializeObject(result, serializerSettings);
Console.WriteLine(newJson);
Это генерирует Json ниже, что идеально
[
{
"key": "name",
"value": "Joe Bloggs"
},
{
"key": "address",
"value": "An adddress somewhere"
},
{
"key": "lastPurchase.PurchaseDateTime",
"value": "01/01/2018 00:00:00"
},
{
"key": "lastPurchase.PurchaseAmount",
"value": "100"
}
]
Ситуация усложняется, когда я представляю сериализацию списка, удаляя JsonIgnore
Теперь я получаю
[
{
"key": "name",
"value": "Joe Bloggs"
},
{
"key": "address",
"value": "An adddress somewhere"
},
{
"key": "lastPurchase.PurchaseDateTime",
"value": "01/01/2018 00:00:00"
},
{
"key": "lastPurchase.PurchaseAmount",
"value": "100"
},
{
"key": "allPurchases",
"value": null
},
{
"key": "allPurchases[0].PurchaseDateTime",
"value": "01/01/2017 00:00:00"
},
{
"key": "allPurchases[0].PurchaseAmount",
"value": "100"
},
{
"key": "allPurchases[1].PurchaseDateTime",
"value": "01/01/2018 00:00:00"
},
{
"key": "allPurchases[1].PurchaseAmount",
"value": "100"
}
]
Это, очевидно, произошло из-за того, что в моей логике c нет ничего конкретного c в нем для обработки списков
Как я могу изменить свои логи c, чтобы AllPurchases был набором пар ключ-значение с ключом allPurchases [0], allPurchases [1], а значение - отдельным ключом сбор значений, который позволил бы избежать имен ключей, таких как allPurchases [0] .PurchaseAmount et c?
Мне нужно оставить решение универсальным c, чтобы оно сгладило любой объект в эту структуру
Пол