In my little library I'm writing as a side project, I'm using RestSharp to get Json from a web API. The deserialization into model classes works fine for simple types, but there are endpoints where the resulting type is unknown (or unclear) at request time.
在我的小库中,我正在编写一个辅助项目,我正在使用RestSharp从Web API获取Json。对模型类进行反序列化对于简单类型可以正常工作,但是在请求时有结果类型未知(或不清楚)的端点。
Specifically its the GuildWars2 API v1 and one example would be item data. There are of course basic properties every item has and additional values are set depending on the queried item. For example a weapon has some modifiers and so on.
具体来说,它的GuildWars2 API v1和一个例子就是项目数据。当然,每个项目都有基本属性,并根据查询的项目设置其他值。例如,武器有一些修饰符等等。
My idea was to create an abstract Item class for all basic properties and derive from that class for all the existing subtypes of items adding needed properties. My problem is, how to decide which subclass to deserialize into. I already read about various methods involving adding a qualified type name to the Json string but since I only get the data from an API, I cannot influence the response im getting.
我的想法是为所有基本属性创建一个抽象的Item类,并从该类派生所有现有的子类型,添加所需的属性。我的问题是,如何决定反序列化的子类。我已经阅读过各种涉及向Json字符串添加限定类型名称的方法,但由于我只从API获取数据,因此无法影响我得到的响应。
I would ideally always want to deserialize into the base class Item with the deserializer deciding the actual type via the given properties contained in the Json string.. Is this a possibility? Or is there a better way to solve this problem?
理想情况下,我总是希望反序列化到基类Item中,反序列化器通过Json字符串中包含的给定属性来确定实际类型。这是否可能?或者有更好的方法来解决这个问题吗?
Thanks in advance
提前致谢
EDIT: This is an example Json of a weapon:
编辑:这是一个武器的Json示例:
{
"item_id": "30704",
"name": "Twilight",
"description": "",
"type": "Weapon",
"level": "80",
"rarity": "Legendary",
"vendor_value": "100000",
"icon_file_id": "456031",
"icon_file_signature": "CE3AF0B7B9BB6244726779F5B6A930541BA6C15F",
"game_types": ["Activity", "Dungeon", "Pve", "Wvw"],
"flags": ["HideSuffix", "NoSell", "SoulBindOnUse"],
"restrictions": [],
"weapon": {
"type": "Greatsword",
"damage_type": "Physical",
"min_power": "995",
"max_power": "1100",
"defense": "0",
"infusion_slots": [],
"infix_upgrade": {
"attributes": [
{
"attribute": "Power",
"modifier": "179"
},
{
"attribute": "Power",
"modifier": "179"
}
]
},
"suffix_item_id": "24599"
}
}
And this would be an armor piece:
这将是一件盔甲:
{
"item_id":"500",
"name":"Carrion Conjurer Chest of Dwayna",
"description":"",
"type":"Armor",
"level":"68",
"rarity":"Rare",
"vendor_value":"257",
"icon_file_id":"61023",
"icon_file_signature":"76CD08463A05730071D400254141B50E570662D3",
"game_types":["Activity", "Dungeon", "Pve", "Wvw"],
"flags":["SoulBindOnUse"],
"restrictions":[],
"armor": {
"type":"Coat",
"weight_class":"Light",
"defense":"221",
"infusion_slots":[],
"infix_upgrade": {
"attributes": [
{
"attribute":"ConditionDamage","modifier":"70"
},
{
"attribute":"Power","modifier":"50"
}
]
},
"suffix_item_id":"24767"
}
}
I'd like to deserialize based on the content of the property "Type", but I cannot figure out, how that would work =/
我想基于属性“类型”的内容反序列化,但我无法弄清楚,这将如何工作= /
1 个解决方案
#1
4
You can parse your JSON data with JObject, which then can be used as an associative array.
您可以使用JObject解析JSON数据,然后可以将其用作关联数组。
string json = @"{
"item_id": "30704",
"name": "Twilight",
"description": "",
"type": "Weapon",
...
}";
JObject o = JObject.Parse(json);
Item item = null;
switch (o["type"])
{
case "Weapon":
item = JsonConvert.DeserializeObject<Weapon>(json);
break;
case "Armor":
item = JsonConvert.DeserializeObject<Armor>(json);
break;
default:
// throw error?
}
and then you'd have a base class as such:
然后你就有了这样一个基类:
public class Item
{
public string item_id { get; set; }
public string name { get; set; }
public string description { get; set; }
public string type { get; set; }
...
// List all common properties here
public Item() { }
// It's important to have the public default constructor implemented
// if you intend on overloading it for your own purpose later
}
And your Weapon class could be as such:
而你的武器类可以是这样的:
public class Weapon : Item // Weapon extends Item
{
public WeaponDetails weapon { get; set; }
public Weapon() { }
}
And Weapon Details:
和武器细节:
public class WeaponDetails
{
public string type { get; set; }
public string damage_type { get; set; }
public int min_power { get; set; }
public int max_power { get; set; }
...
public WeaponDetails() { }
}
#1
4
You can parse your JSON data with JObject, which then can be used as an associative array.
您可以使用JObject解析JSON数据,然后可以将其用作关联数组。
string json = @"{
"item_id": "30704",
"name": "Twilight",
"description": "",
"type": "Weapon",
...
}";
JObject o = JObject.Parse(json);
Item item = null;
switch (o["type"])
{
case "Weapon":
item = JsonConvert.DeserializeObject<Weapon>(json);
break;
case "Armor":
item = JsonConvert.DeserializeObject<Armor>(json);
break;
default:
// throw error?
}
and then you'd have a base class as such:
然后你就有了这样一个基类:
public class Item
{
public string item_id { get; set; }
public string name { get; set; }
public string description { get; set; }
public string type { get; set; }
...
// List all common properties here
public Item() { }
// It's important to have the public default constructor implemented
// if you intend on overloading it for your own purpose later
}
And your Weapon class could be as such:
而你的武器类可以是这样的:
public class Weapon : Item // Weapon extends Item
{
public WeaponDetails weapon { get; set; }
public Weapon() { }
}
And Weapon Details:
和武器细节:
public class WeaponDetails
{
public string type { get; set; }
public string damage_type { get; set; }
public int min_power { get; set; }
public int max_power { get; set; }
...
public WeaponDetails() { }
}