假设我有以下json。
{
"allitemscount":2,
"allitems":[
{"itemid":"1","itemname":"one"},
{"itemid":"2","itemname":"two"}],
"customitems":[
{"itemid":"3","itemname":"three"},
{"itemid":"4","itemname":"four"}]
}
当反序列化这个json时,它应该转到下面的C#模型。
public class response
{
public int allitemscount;
public List<item> items;
}
public class item
{
public string itemid;
public string itemname;
}
问题:
如何根据条件在allitems
和customitems
之间切换?例如,如果useAllitems
为真,则来自json的allitems
将填入项目,如果useCustomItems
为真,则customitems
将填入项属性。请帮忙说明如何做到这一点。
在public List<item> items
上使用JsonProperty允许在allitems
之间切换,但有没有办法根据上述条件进行反序列化。
答案 0 :(得分:2)
我编写了自己的继承自JsonConverter的ItemConverter,
我在尝试时使用的示例模型json:
{
"allitemscount": 2,
"UseCustomItems": true,
"allitems": [
{
"itemid": "1",
"itemname": "one"
},
{
"itemid": "2",
"itemname": "two"
}
],
"customitems": [
{
"itemid": "3",
"itemname": "three"
},
{
"itemid": "4",
"itemname": "four"
}
]
}
控制台应用程序的主要方法:
static void Main(string[] args)
{
using (StreamReader r = new StreamReader(@"\model.json")) // json path
{
string json = r.ReadToEnd();
var deserializedJson = JsonConvert.DeserializeObject<Result>(json, new ItemConverter());
}
}
型号:
public class Result // main object
{
[JsonProperty("allitemscount")]
public long Allitemscount { get; set; }
public bool UseCustomItems { get; set; }
}
public class ResultA : Result // CustomItems Model
{
[JsonProperty("customitems")]
private List<Item> Items { get; set; }
}
public class ResultB : Result // AllItems Model
{
[JsonProperty("allitems")]
private List<Item> Items { get; set; }
}
public class Item
{
[JsonProperty("itemid")]
public string Itemid { get; set; }
[JsonProperty("itemname")]
public string Itemname { get; set; }
}
我们在反序列化时使用的ItemConverter:
internal class ItemConverter : JsonConverter
{
private Type currentType;
public override bool CanConvert(Type objectType)
{
return typeof(Item).IsAssignableFrom(objectType) || objectType == typeof(Result);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject item = JObject.Load(reader);
if (item["UseCustomItems"] != null)
{
// save the type for later.
switch (item["UseCustomItems"].Value<bool>())
{
case true:
currentType = typeof(ResultA);
return item.ToObject<ResultA>(); // return result as customitems result
case false:
currentType = typeof(ResultB);
return item.ToObject<ResultB>(); // return result as allitems result
}
return item.ToObject<Result>();
}
// use the last type you read to serialise.
return item.ToObject(currentType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
我希望此解决方案对您有所帮助
答案 1 :(得分:0)
您可以通过更改response
类来反序列化上面的json,如下所示
public class response{
public int allitemscount;
public List<item> allitems;
public List<item> customitems;
}
然后使用以下代码
var jsonData = "{\"allitemscount\":2, \"allitems\":[{\"itemid\":\"1\",\"itemname\":\"one\"}, {\"itemid\":\"2\",\"itemname\":\"two\"}],\"customitems\":[{\"itemid\":\"3\",\"itemname\":\"three\"},{\"itemid\":\"4\",\"itemname\":\"four\"}]}";
var data = JsonConvert.DeserializeObject<response>(jsonData);
foreach(var str in data.allitems) {
Console.WriteLine(str.itemid +'-'+str.itemname);
}
foreach(var str in data.customitems) {
Console.WriteLine(str.itemid +'-'+str.itemname);
}