无法将 JSON 反序列化为具有嵌套列表的对象
Can't deserialize JSON into an object with nested list
很抱歉问了一个相当常见的问题,我一直在寻找,但找不到解决我问题的解决方案。
我正在使用 Firesharp,并尝试将 Firebase returns 的 Json 对象反序列化为具有嵌套列表的 class。
public class Class
{
public string Name { get; set; }
public string Desc { get; set; }
public string HPDie { get; set; }
public string Role { get; set; }
public int RPL { get; set; }
public IList<Level> Levels { get; set; }
public Class() { }
public Class(string name, string desc, string hpdie, string role, int rPL, List<Level> levels)
{
Name = name;
Desc = desc;
HPDie = hpdie;
RPL = rPL;
Levels = levels;
}
}
如您所见,它有一个级别列表,另一个 class 具有以下代码:
public class Level
{
public int Number { get; set; }
public int BAB { get; set; }
public int FortSave { get; set; }
public int WillSave { get; set; }
public int RexSave { get; set; }
public int SpellsKnown { get; set; }
public List<Skill> Skills { get; set; }
public Level() { }
public Level(int number, int bab, int cmb, int cmd, int fortsave, int willsave, int rexsave, List<Skill> skills)
{
Number = number;
BAB = bab;
FortSave = fortsave;
WillSave = willsave;
RexSave = rexsave;
Skills = skills;
}
public class LevelList
{
List<Level> levellist { get; set; }
}
}
同时,有一个技能列表。技能 class 只有两个字符串,一个名称和一个描述。
我用来反序列化的代码是:
private async void RefreshClasses()
{
this.classList = new List<Class>();
FirebaseResponse res = await client.GetAsync("Class");
IEnumerable<Class> data = JsonConvert.DeserializeObject<IEnumerable<Class>>(res.Body);
if (data != null)
{
PopulateDGVClasses(data);
}
}
但是当它进行反序列化时 returns 出现以下错误:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the
current JSON object (e.g. {"name":"value"}) into type
'System.Collections.Generic.IEnumerable`1[CaminanteHelper.Class]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly. To fix this error either change the JSON to a JSON array
(e.g. [1,2,3]) or change the deserialized type so that it is a normal
.NET type (e.g. not a primitive type like integer, not a collection
type like an array or List) that can be deserialized from a JSON
object. JsonObjectAttribute can also be added to the type to force it
to deserialize from a JSON object. Path 'Barbarian', line 1, position
13.'
同样,我想我应该可以自己解决这个问题,但是我已经卡了将近两天了。
提前谢谢大家!
编辑:Json 我正在尝试反序列化:
{
"Class" : {
"Barbarian" : {
"Desc" : "Barbarians excel in combat, possessing the martial prowess and fortitude to take on foes seemingly far superior to themselves. With rage granting them boldness and daring beyond that of most other warriors, barbarians charge furiously into battle and ruin all who would stand in their way.",
"HPDie" : "d12",
"Levels" : [ {
"BAB" : 2,
"FortSave" : 2,
"Number" : 1,
"RexSave" : 0,
"Skills" : {
"Prueba" : {
"Desc" : "Probota"
}
},
"SpellsKnown" : 0,
"WillSave" : 0
}, {
"BAB" : 3,
"FortSave" : 3,
"Number" : 2,
"RexSave" : 0,
"SpellsKnown" : 0,
"WillSave" : 0
}, {
"BAB" : 3,
"FortSave" : 3,
"Number" : 3,
"RexSave" : 1,
"SpellsKnown" : 0,
"WillSave" : 1
}, {
"BAB" : 4,
"FortSave" : 4,
"Number" : 4,
"RexSave" : 1,
"SpellsKnown" : 0,
"WillSave" : 1
}, {
"BAB" : 5,
"FortSave" : 4,
"Number" : 5,
"RexSave" : 1,
"SpellsKnown" : 0,
"WillSave" : 1
}, {
"BAB" : 6,
"FortSave" : 5,
"Number" : 6,
"RexSave" : 2,
"SpellsKnown" : 0,
"WillSave" : 2
}, {
"BAB" : 7,
"FortSave" : 5,
"Number" : 7,
"RexSave" : 2,
"SpellsKnown" : 0,
"WillSave" : 2
}, {
"BAB" : 8,
"FortSave" : 6,
"Number" : 8,
"RexSave" : 2,
"SpellsKnown" : 0,
"WillSave" : 2
}, {
"BAB" : 9,
"FortSave" : 6,
"Number" : 9,
"RexSave" : 3,
"SpellsKnown" : 0,
"WillSave" : 3
}, {
"BAB" : 10,
"FortSave" : 7,
"Number" : 10,
"RexSave" : 3,
"SpellsKnown" : 0,
"WillSave" : 3
} ],
"Name" : "Barbarian",
"RPL" : 4
},
"Wizard" : {
"Desc" : "While universalist wizards might study to prepare themselves for any manner of danger, specialist wizards research schools of magic that make them exceptionally skilled within a specific focus. \r\n\r\nYet no matter their specialty, all wizards are masters of the impossible and can aid their allies in overcoming any danger.",
"HPDie" : "d6",
"Levels" : [ {
"BAB" : 0,
"FortSave" : 0,
"Number" : 1,
"RexSave" : 0,
"SpellsKnown" : 4,
"WillSave" : 2
}, {
"BAB" : 1,
"FortSave" : 0,
"Number" : 2,
"RexSave" : 0,
"SpellsKnown" : 6,
"WillSave" : 3
}, {
"BAB" : 1,
"FortSave" : 1,
"Number" : 3,
"RexSave" : 1,
"SpellsKnown" : 7,
"WillSave" : 3
}, {
"BAB" : 2,
"FortSave" : 1,
"Number" : 4,
"RexSave" : 1,
"SpellsKnown" : 9,
"WillSave" : 4
}, {
"BAB" : 2,
"FortSave" : 1,
"Number" : 5,
"RexSave" : 1,
"SpellsKnown" : 10,
"WillSave" : 4
}, {
"BAB" : 3,
"FortSave" : 2,
"Number" : 6,
"RexSave" : 2,
"SpellsKnown" : 12,
"WillSave" : 5
}, {
"BAB" : 3,
"FortSave" : 2,
"Number" : 7,
"RexSave" : 2,
"SpellsKnown" : 14,
"WillSave" : 5
}, {
"BAB" : 4,
"FortSave" : 2,
"Number" : 8,
"RexSave" : 2,
"SpellsKnown" : 16,
"WillSave" : 6
}, {
"BAB" : 4,
"FortSave" : 3,
"Number" : 9,
"RexSave" : 3,
"SpellsKnown" : 18,
"WillSave" : 6
}, {
"BAB" : 5,
"FortSave" : 3,
"Number" : 10,
"RexSave" : 3,
"SpellsKnown" : 20,
"WillSave" : 7
} ],
"Name" : "Wizard",
"RPL" : 2
}
},
"Equipment" : {
"Battleaxe" : {
"ACBonus" : 0,
"ACType" : "(None)",
"Blunt" : false,
"Bonus" : "",
"Category" : "Weapon",
"Cost" : "10gp",
"DMG_Large" : "1d10",
"DMG_Medium" : "1d8",
"DMG_Small" : "1d6",
"Description" : "The handle of this axe is long enough that you can wield it one-handed or two-handed. The head may have one blade or two, with blade shapes ranging from half-moons to squared edges like narrower versions of woodcutting axes. The wooden haft may be protected and strengthened with metal bands called langets.",
"Name" : "Battleaxe",
"Penetrating" : false,
"Range" : "",
"Slashing" : true,
"Throwable" : false
},
"Composite Longbow" : {
"ACBonus" : 0,
"ACType" : "(None)",
"Blunt" : false,
"Bonus" : "If your STR is equal or more than the rating, add your STR bonus to damage made with this weapon.",
"Category" : "Weapon",
"Cost" : "100gp",
"DMG_Large" : "1d10",
"DMG_Medium" : "1d8",
"DMG_Small" : "1d6",
"Description" : "You need at least two hands to use a bow, regardless of its size. You can use a composite longbow while mounted.",
"Name" : "Composite Longbow",
"Penetrating" : true,
"Range" : "110ft",
"Slashing" : false,
"Throwable" : false
},
"Dagger" : {
"ACBonus" : 0,
"ACType" : "(None)",
"Blunt" : false,
"Bonus" : "+2 to Steal rolls made to hide this weapon.",
"Category" : "Weapon",
"Cost" : "6gp",
"DMG_Large" : "1d6",
"DMG_Medium" : "1d4",
"DMG_Small" : "1d3",
"Description" : "A one handed broad blade, shorter than a shortsword yet longer than a knife.",
"Name" : "Dagger",
"Penetrating" : true,
"Range" : "10ft",
"Slashing" : true,
"Throwable" : true
},
"Shield" : {
"ACBonus" : 2,
"ACType" : "Light",
"Blunt" : true,
"Bonus" : "",
"Category" : "Armor",
"Cost" : "12gp",
"DMG_Large" : "1d6",
"DMG_Medium" : "1d4",
"DMG_Small" : "1d2",
"Description" : "Made of leather.",
"Name" : "Shield",
"Penetrating" : false,
"Range" : "",
"Slashing" : false,
"Throwable" : false
},
"Sword" : {
"ACBonus" : 0,
"ACType" : "(None)",
"Blunt" : false,
"Bonus" : "",
"Category" : "Weapon",
"Cost" : "15gp",
"DMG_Large" : "1d10",
"DMG_Medium" : "1d8",
"DMG_Small" : "1d6",
"Description" : "This sword is about three and a half feet in length.",
"Name" : "Sword",
"Penetrating" : false,
"Range" : "",
"Slashing" : true,
"Throwable" : false
}
},
"Feat" : {
"Acrobatic" : {
"Desc" : "+2 to all of your Acrobatic rolls per each five character levels.",
"Name" : "Acrobatic",
"PreReq" : [ "" ],
"Type" : "General"
},
"Agile Maiden" : {
"Desc" : "For the purpose of class features (such as a ranger’s combat style, a barbarian’s fast movement, or a magus’s spellcasting), you treat Gray Maiden plate as medium armor or heavy armor, whichever is more beneficial to a given ability. This does not affect the armor’s statistics, and it is still considered heavy armor for all other purposes",
"Name" : "Agile Maiden",
"PreReq" : [ "Str 13", "Dex 13" ],
"Type" : "Combat"
}
},
"Spell" : {
"Cure Minor Wounds" : {
"CastingTime" : "None.",
"Desc" : "When laying your hand upon a living creature, you channel positive energy that cures 1d8 points of damage +1 point per caster level (maximum +5). Since undead are powered by negative energy, this spell deals damage to them instead of curing their wounds. An undead creature can apply Spell Resistance, and can attempt a Will save to take half damage.",
"Duration" : "Instantaneous.",
"FortRes" : false,
"Name" : "Cure Minor Wounds",
"PreReq" : [ "1 Divine" ],
"RexRes" : false,
"School" : "Conjuration",
"Target" : "Touched Creature.",
"WillRes" : true
},
"Magic Missile" : {
"CastingTime" : "None.",
"Desc" : "A missile of magical energy darts forth from your fingertip and strikes its target, dealing 1d4+1 points of force damage.\r\n\r\nThe missile strikes unerringly, even if the target is in melee combat, so long as it has less than total cover or total concealment. Specific parts of a creature can’t be singled out. Objects are not damaged by the spell.\r\n\r\nFor every two caster levels beyond 1st, you gain an additional missile – two at 3rd level, three at 5th, four at 7th, and the maximum of five missiles at 9th level or higher. If you shoot multiple missiles, you can have them strike a single creature or several creatures. A single missile can strike only one creature. You must designate targets before you check for spell resistance or roll damage.",
"Duration" : "Instantaneous.",
"FortRes" : false,
"Name" : "Magic Missile",
"PreReq" : [ "1 Divine\r\n1 Arcane\r\n1 Divine\r\n1 Arcane\r\n1 Divine\r\n1 Arcane\r\n" ],
"RexRes" : false,
"School" : "Evocation",
"Target" : "Up to five none of which can be separated by more than 15 ft.",
"WillRes" : false
}
}
}
这绝不是一个完整的答案。我假设你不想 map/create classes 为每个“sub class”,例如Barbarian、Wizard 等。您也许可以使用 JsonConverter。该示例仅处理第一个“匿名”对象范围。也许您会发现其中一些有用。
var result = JsonConvert.DeserializeObject<Response>(jsonInput);
public class ClassJsonConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return new Class
{
ClassSpecifics = JObject.Load(reader).Values().Select(x => x.ToObject<ClassSpecifics>()).ToList()
};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); }
public override bool CanConvert(Type objectType) { throw new NotImplementedException(); }
}
public class Response
{
public Class Class { get; set; }
}
[JsonConverter(typeof(ClassJsonConverter))]
public class Class
{
public List<ClassSpecifics> ClassSpecifics { get; set; }
}
public class ClassSpecifics
{
public string Name { get; set; }
public string Desc { get; set; }
public string HPDie { get; set; }
public string Role { get; set; }
public int RPL { get; set; }
}
很抱歉问了一个相当常见的问题,我一直在寻找,但找不到解决我问题的解决方案。
我正在使用 Firesharp,并尝试将 Firebase returns 的 Json 对象反序列化为具有嵌套列表的 class。
public class Class
{
public string Name { get; set; }
public string Desc { get; set; }
public string HPDie { get; set; }
public string Role { get; set; }
public int RPL { get; set; }
public IList<Level> Levels { get; set; }
public Class() { }
public Class(string name, string desc, string hpdie, string role, int rPL, List<Level> levels)
{
Name = name;
Desc = desc;
HPDie = hpdie;
RPL = rPL;
Levels = levels;
}
}
如您所见,它有一个级别列表,另一个 class 具有以下代码:
public class Level
{
public int Number { get; set; }
public int BAB { get; set; }
public int FortSave { get; set; }
public int WillSave { get; set; }
public int RexSave { get; set; }
public int SpellsKnown { get; set; }
public List<Skill> Skills { get; set; }
public Level() { }
public Level(int number, int bab, int cmb, int cmd, int fortsave, int willsave, int rexsave, List<Skill> skills)
{
Number = number;
BAB = bab;
FortSave = fortsave;
WillSave = willsave;
RexSave = rexsave;
Skills = skills;
}
public class LevelList
{
List<Level> levellist { get; set; }
}
}
同时,有一个技能列表。技能 class 只有两个字符串,一个名称和一个描述。
我用来反序列化的代码是:
private async void RefreshClasses()
{
this.classList = new List<Class>();
FirebaseResponse res = await client.GetAsync("Class");
IEnumerable<Class> data = JsonConvert.DeserializeObject<IEnumerable<Class>>(res.Body);
if (data != null)
{
PopulateDGVClasses(data);
}
}
但是当它进行反序列化时 returns 出现以下错误:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IEnumerable`1[CaminanteHelper.Class]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'Barbarian', line 1, position 13.'
同样,我想我应该可以自己解决这个问题,但是我已经卡了将近两天了。
提前谢谢大家!
编辑:Json 我正在尝试反序列化:
{
"Class" : {
"Barbarian" : {
"Desc" : "Barbarians excel in combat, possessing the martial prowess and fortitude to take on foes seemingly far superior to themselves. With rage granting them boldness and daring beyond that of most other warriors, barbarians charge furiously into battle and ruin all who would stand in their way.",
"HPDie" : "d12",
"Levels" : [ {
"BAB" : 2,
"FortSave" : 2,
"Number" : 1,
"RexSave" : 0,
"Skills" : {
"Prueba" : {
"Desc" : "Probota"
}
},
"SpellsKnown" : 0,
"WillSave" : 0
}, {
"BAB" : 3,
"FortSave" : 3,
"Number" : 2,
"RexSave" : 0,
"SpellsKnown" : 0,
"WillSave" : 0
}, {
"BAB" : 3,
"FortSave" : 3,
"Number" : 3,
"RexSave" : 1,
"SpellsKnown" : 0,
"WillSave" : 1
}, {
"BAB" : 4,
"FortSave" : 4,
"Number" : 4,
"RexSave" : 1,
"SpellsKnown" : 0,
"WillSave" : 1
}, {
"BAB" : 5,
"FortSave" : 4,
"Number" : 5,
"RexSave" : 1,
"SpellsKnown" : 0,
"WillSave" : 1
}, {
"BAB" : 6,
"FortSave" : 5,
"Number" : 6,
"RexSave" : 2,
"SpellsKnown" : 0,
"WillSave" : 2
}, {
"BAB" : 7,
"FortSave" : 5,
"Number" : 7,
"RexSave" : 2,
"SpellsKnown" : 0,
"WillSave" : 2
}, {
"BAB" : 8,
"FortSave" : 6,
"Number" : 8,
"RexSave" : 2,
"SpellsKnown" : 0,
"WillSave" : 2
}, {
"BAB" : 9,
"FortSave" : 6,
"Number" : 9,
"RexSave" : 3,
"SpellsKnown" : 0,
"WillSave" : 3
}, {
"BAB" : 10,
"FortSave" : 7,
"Number" : 10,
"RexSave" : 3,
"SpellsKnown" : 0,
"WillSave" : 3
} ],
"Name" : "Barbarian",
"RPL" : 4
},
"Wizard" : {
"Desc" : "While universalist wizards might study to prepare themselves for any manner of danger, specialist wizards research schools of magic that make them exceptionally skilled within a specific focus. \r\n\r\nYet no matter their specialty, all wizards are masters of the impossible and can aid their allies in overcoming any danger.",
"HPDie" : "d6",
"Levels" : [ {
"BAB" : 0,
"FortSave" : 0,
"Number" : 1,
"RexSave" : 0,
"SpellsKnown" : 4,
"WillSave" : 2
}, {
"BAB" : 1,
"FortSave" : 0,
"Number" : 2,
"RexSave" : 0,
"SpellsKnown" : 6,
"WillSave" : 3
}, {
"BAB" : 1,
"FortSave" : 1,
"Number" : 3,
"RexSave" : 1,
"SpellsKnown" : 7,
"WillSave" : 3
}, {
"BAB" : 2,
"FortSave" : 1,
"Number" : 4,
"RexSave" : 1,
"SpellsKnown" : 9,
"WillSave" : 4
}, {
"BAB" : 2,
"FortSave" : 1,
"Number" : 5,
"RexSave" : 1,
"SpellsKnown" : 10,
"WillSave" : 4
}, {
"BAB" : 3,
"FortSave" : 2,
"Number" : 6,
"RexSave" : 2,
"SpellsKnown" : 12,
"WillSave" : 5
}, {
"BAB" : 3,
"FortSave" : 2,
"Number" : 7,
"RexSave" : 2,
"SpellsKnown" : 14,
"WillSave" : 5
}, {
"BAB" : 4,
"FortSave" : 2,
"Number" : 8,
"RexSave" : 2,
"SpellsKnown" : 16,
"WillSave" : 6
}, {
"BAB" : 4,
"FortSave" : 3,
"Number" : 9,
"RexSave" : 3,
"SpellsKnown" : 18,
"WillSave" : 6
}, {
"BAB" : 5,
"FortSave" : 3,
"Number" : 10,
"RexSave" : 3,
"SpellsKnown" : 20,
"WillSave" : 7
} ],
"Name" : "Wizard",
"RPL" : 2
}
},
"Equipment" : {
"Battleaxe" : {
"ACBonus" : 0,
"ACType" : "(None)",
"Blunt" : false,
"Bonus" : "",
"Category" : "Weapon",
"Cost" : "10gp",
"DMG_Large" : "1d10",
"DMG_Medium" : "1d8",
"DMG_Small" : "1d6",
"Description" : "The handle of this axe is long enough that you can wield it one-handed or two-handed. The head may have one blade or two, with blade shapes ranging from half-moons to squared edges like narrower versions of woodcutting axes. The wooden haft may be protected and strengthened with metal bands called langets.",
"Name" : "Battleaxe",
"Penetrating" : false,
"Range" : "",
"Slashing" : true,
"Throwable" : false
},
"Composite Longbow" : {
"ACBonus" : 0,
"ACType" : "(None)",
"Blunt" : false,
"Bonus" : "If your STR is equal or more than the rating, add your STR bonus to damage made with this weapon.",
"Category" : "Weapon",
"Cost" : "100gp",
"DMG_Large" : "1d10",
"DMG_Medium" : "1d8",
"DMG_Small" : "1d6",
"Description" : "You need at least two hands to use a bow, regardless of its size. You can use a composite longbow while mounted.",
"Name" : "Composite Longbow",
"Penetrating" : true,
"Range" : "110ft",
"Slashing" : false,
"Throwable" : false
},
"Dagger" : {
"ACBonus" : 0,
"ACType" : "(None)",
"Blunt" : false,
"Bonus" : "+2 to Steal rolls made to hide this weapon.",
"Category" : "Weapon",
"Cost" : "6gp",
"DMG_Large" : "1d6",
"DMG_Medium" : "1d4",
"DMG_Small" : "1d3",
"Description" : "A one handed broad blade, shorter than a shortsword yet longer than a knife.",
"Name" : "Dagger",
"Penetrating" : true,
"Range" : "10ft",
"Slashing" : true,
"Throwable" : true
},
"Shield" : {
"ACBonus" : 2,
"ACType" : "Light",
"Blunt" : true,
"Bonus" : "",
"Category" : "Armor",
"Cost" : "12gp",
"DMG_Large" : "1d6",
"DMG_Medium" : "1d4",
"DMG_Small" : "1d2",
"Description" : "Made of leather.",
"Name" : "Shield",
"Penetrating" : false,
"Range" : "",
"Slashing" : false,
"Throwable" : false
},
"Sword" : {
"ACBonus" : 0,
"ACType" : "(None)",
"Blunt" : false,
"Bonus" : "",
"Category" : "Weapon",
"Cost" : "15gp",
"DMG_Large" : "1d10",
"DMG_Medium" : "1d8",
"DMG_Small" : "1d6",
"Description" : "This sword is about three and a half feet in length.",
"Name" : "Sword",
"Penetrating" : false,
"Range" : "",
"Slashing" : true,
"Throwable" : false
}
},
"Feat" : {
"Acrobatic" : {
"Desc" : "+2 to all of your Acrobatic rolls per each five character levels.",
"Name" : "Acrobatic",
"PreReq" : [ "" ],
"Type" : "General"
},
"Agile Maiden" : {
"Desc" : "For the purpose of class features (such as a ranger’s combat style, a barbarian’s fast movement, or a magus’s spellcasting), you treat Gray Maiden plate as medium armor or heavy armor, whichever is more beneficial to a given ability. This does not affect the armor’s statistics, and it is still considered heavy armor for all other purposes",
"Name" : "Agile Maiden",
"PreReq" : [ "Str 13", "Dex 13" ],
"Type" : "Combat"
}
},
"Spell" : {
"Cure Minor Wounds" : {
"CastingTime" : "None.",
"Desc" : "When laying your hand upon a living creature, you channel positive energy that cures 1d8 points of damage +1 point per caster level (maximum +5). Since undead are powered by negative energy, this spell deals damage to them instead of curing their wounds. An undead creature can apply Spell Resistance, and can attempt a Will save to take half damage.",
"Duration" : "Instantaneous.",
"FortRes" : false,
"Name" : "Cure Minor Wounds",
"PreReq" : [ "1 Divine" ],
"RexRes" : false,
"School" : "Conjuration",
"Target" : "Touched Creature.",
"WillRes" : true
},
"Magic Missile" : {
"CastingTime" : "None.",
"Desc" : "A missile of magical energy darts forth from your fingertip and strikes its target, dealing 1d4+1 points of force damage.\r\n\r\nThe missile strikes unerringly, even if the target is in melee combat, so long as it has less than total cover or total concealment. Specific parts of a creature can’t be singled out. Objects are not damaged by the spell.\r\n\r\nFor every two caster levels beyond 1st, you gain an additional missile – two at 3rd level, three at 5th, four at 7th, and the maximum of five missiles at 9th level or higher. If you shoot multiple missiles, you can have them strike a single creature or several creatures. A single missile can strike only one creature. You must designate targets before you check for spell resistance or roll damage.",
"Duration" : "Instantaneous.",
"FortRes" : false,
"Name" : "Magic Missile",
"PreReq" : [ "1 Divine\r\n1 Arcane\r\n1 Divine\r\n1 Arcane\r\n1 Divine\r\n1 Arcane\r\n" ],
"RexRes" : false,
"School" : "Evocation",
"Target" : "Up to five none of which can be separated by more than 15 ft.",
"WillRes" : false
}
}
}
这绝不是一个完整的答案。我假设你不想 map/create classes 为每个“sub class”,例如Barbarian、Wizard 等。您也许可以使用 JsonConverter。该示例仅处理第一个“匿名”对象范围。也许您会发现其中一些有用。
var result = JsonConvert.DeserializeObject<Response>(jsonInput);
public class ClassJsonConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return new Class
{
ClassSpecifics = JObject.Load(reader).Values().Select(x => x.ToObject<ClassSpecifics>()).ToList()
};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); }
public override bool CanConvert(Type objectType) { throw new NotImplementedException(); }
}
public class Response
{
public Class Class { get; set; }
}
[JsonConverter(typeof(ClassJsonConverter))]
public class Class
{
public List<ClassSpecifics> ClassSpecifics { get; set; }
}
public class ClassSpecifics
{
public string Name { get; set; }
public string Desc { get; set; }
public string HPDie { get; set; }
public string Role { get; set; }
public int RPL { get; set; }
}