Json.NET - 将多个对象属性自定义反序列化为单一类型列表?
Json.NET - Custom deserialization of multiple object properties to list of single type?
我一直在尝试想出 simplest/cleanest 方法来处理这个问题,但经过几次重构后,我还是离不开它。我希望这里有人可以提供帮助。
从我调用的服务返回的 JSON 是不可预测的,并且会不断更新。
示例:
{
SomeKey : "SomeValue",
SecondaryProperties: {
Property1: { "Id" : "ABC", "Label" : "Property One", "Value" : 1 },
Property2: { "Id" : "DEF", "Label" : "Property Two", "Value" : 10 },
Property3: { "Id" : "GHI", "Label" : "Property Three", "Value" : 5 },
Banana: { "Id" : "YUM", "Label" : "Property Four", "Value" : 5 },
WeJustAddedThis: { "Id" : "XYZ", "Label" : "Property Five", "Value" : 1 }
}
}
由于这些辅助 属性 键在不断变化(注意:值得庆幸的是值总是一致的!),创建一个具有每个属性的对象没有什么意义,因为我会经常更新对象除非有人告诉我一个新的数据点被添加到 API 数据中,否则它永远不会出现在应用程序中,直到代码被更新。
所以我想创建一个自定义属性转换器,它会生成一个 SecondaryProperty
对象的列表。类似于:
public class SecondaryProperties {
public string SomeKey { get; set; }
[JsonConverter(typeof(SecondaryPropertyConverter))]
public List<SecondaryProperty> PropertyList { get; set; }
}
public class SecondaryProperty {
public string Id { get; set; }
public string Label { get; set; }
public int Value { get; set; }
}
// This is where things get hazy for me
public class SecondaryPropertyConverter: JsonConverter {
...
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
var ratings = new List<SecondaryProperty>();
var obj = JObject.Load(reader);
foreach(var property in obj.Properties()){
var rating = property.Value<SecondaryProperty>();
ratings.Add(rating);
}
return ratings;
}
}
我认为我在正确的轨道上,但列表总是空的,很明显我遗漏了一些东西。谁能提供一些见解?
非常感谢!
不需要任何花哨的东西,如果新项目都具有一致的模式,我们可以这样做:
void Main()
{
var json= @"{
SomeKey : ""SomeValue"",
SecondaryProperties: {
Property1: { ""Id"" : ""ABC"", ""Label"" : ""Property One"", ""Value"" : 1 },
Property2: { ""Id"" : ""DEF"", ""Label"" : ""Property Two"", ""Value"" : 10 },
Property3: { ""Id"" : ""GHI"", ""Label"" : ""Property Three"", ""Value"" : 5 },
Banana: { ""Id"" : ""YUM"", ""Label"" : ""Property Four"", ""Value"" : 5 },
WeJustAddedThis: { ""Id"" : ""XYZ"", ""Label"" : ""Property Five"", ""Value"" : 1 }
}
}";
var result = JsonConvert.DeserializeObject<Root>(json);
}
public class Property
{
[JsonProperty("Id")]
public string Id { get; set; }
[JsonProperty("Label")]
public string Label { get; set; }
[JsonProperty("Value")]
public int Value { get; set; }
}
public class Root
{
[JsonProperty("SomeKey")]
public string SomeKey { get; set; }
[JsonProperty("SecondaryProperties")]
public Dictionary<string, Property> SecondaryProperties { get; set; }
}
我一直在尝试想出 simplest/cleanest 方法来处理这个问题,但经过几次重构后,我还是离不开它。我希望这里有人可以提供帮助。
从我调用的服务返回的 JSON 是不可预测的,并且会不断更新。
示例:
{
SomeKey : "SomeValue",
SecondaryProperties: {
Property1: { "Id" : "ABC", "Label" : "Property One", "Value" : 1 },
Property2: { "Id" : "DEF", "Label" : "Property Two", "Value" : 10 },
Property3: { "Id" : "GHI", "Label" : "Property Three", "Value" : 5 },
Banana: { "Id" : "YUM", "Label" : "Property Four", "Value" : 5 },
WeJustAddedThis: { "Id" : "XYZ", "Label" : "Property Five", "Value" : 1 }
}
}
由于这些辅助 属性 键在不断变化(注意:值得庆幸的是值总是一致的!),创建一个具有每个属性的对象没有什么意义,因为我会经常更新对象除非有人告诉我一个新的数据点被添加到 API 数据中,否则它永远不会出现在应用程序中,直到代码被更新。
所以我想创建一个自定义属性转换器,它会生成一个 SecondaryProperty
对象的列表。类似于:
public class SecondaryProperties {
public string SomeKey { get; set; }
[JsonConverter(typeof(SecondaryPropertyConverter))]
public List<SecondaryProperty> PropertyList { get; set; }
}
public class SecondaryProperty {
public string Id { get; set; }
public string Label { get; set; }
public int Value { get; set; }
}
// This is where things get hazy for me
public class SecondaryPropertyConverter: JsonConverter {
...
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
var ratings = new List<SecondaryProperty>();
var obj = JObject.Load(reader);
foreach(var property in obj.Properties()){
var rating = property.Value<SecondaryProperty>();
ratings.Add(rating);
}
return ratings;
}
}
我认为我在正确的轨道上,但列表总是空的,很明显我遗漏了一些东西。谁能提供一些见解?
非常感谢!
不需要任何花哨的东西,如果新项目都具有一致的模式,我们可以这样做:
void Main()
{
var json= @"{
SomeKey : ""SomeValue"",
SecondaryProperties: {
Property1: { ""Id"" : ""ABC"", ""Label"" : ""Property One"", ""Value"" : 1 },
Property2: { ""Id"" : ""DEF"", ""Label"" : ""Property Two"", ""Value"" : 10 },
Property3: { ""Id"" : ""GHI"", ""Label"" : ""Property Three"", ""Value"" : 5 },
Banana: { ""Id"" : ""YUM"", ""Label"" : ""Property Four"", ""Value"" : 5 },
WeJustAddedThis: { ""Id"" : ""XYZ"", ""Label"" : ""Property Five"", ""Value"" : 1 }
}
}";
var result = JsonConvert.DeserializeObject<Root>(json);
}
public class Property
{
[JsonProperty("Id")]
public string Id { get; set; }
[JsonProperty("Label")]
public string Label { get; set; }
[JsonProperty("Value")]
public int Value { get; set; }
}
public class Root
{
[JsonProperty("SomeKey")]
public string SomeKey { get; set; }
[JsonProperty("SecondaryProperties")]
public Dictionary<string, Property> SecondaryProperties { get; set; }
}