使用 newtonsoft 将 class 中没有 属性 的值反序列化为 fill/match
Deserializing a value with no property to fill/match in class using newtonsoft
我正在使用 C# 和 NewtonSoft 框架反序列化 json。
JSON 来自 http://hearthstonejson.com/。
看起来像这样。 http://i.imgur.com/8pmxLYd.png
{"Basic":[
{"id":"GAME_004","name":"AFK","type":"Enchantment","text":"Your turns are shorter."},
{"id":"EX1_066","name":"Acidic Swamp Ooze","type":"Minion","faction":"Alliance","rarity":"Common","cost":2,"attack":3,"health":2,"text":"<b>Battlecry:</b> Destroy your opponent's weapon.","flavor":"Oozes love Flamenco. Don't ask.","artist":"Chris Rahn","collectible":true,"howToGetGold":"Unlocked at Rogue Level 57.","mechanics":["Battlecry"]},
我可以很容易地一次反序列化一个集合到我的 classes 中,但不能一次反序列化所有集合。对我来说,我不明白的问题是反序列化器会正确地为每个 属性 填充一个值,但是如果一个值存在而前面没有要填充的 属性 怎么办。
"id":"GAME_004"
很容易填入
public string id;
但是
{"Basic":[{"id":"GAME_004",
("basic") 或任何其他卡组名称不会填写任何内容,除非它有一个 属性 匹配。我假设我不需要提前知道卡组名称是什么。我应该能够将每个集合填充到一个集合中而不必知道名称或者这是错误的吗?我可以不将每个对象的开头自动分配给 class 中的 属性 而不必特别知道名称吗?
Token: StartObject
Token: PropertyName, Value: Basic
Token: StartArray
Token: StartObject
Token: PropertyName, Value: id
Token: String, Value: GAME_004
或者我必须对每个单独的集合执行以下操作吗?或者我错过了构建 classes 的步骤。
List<IList<Card>> setsList = new List<IList<Card>>();
JObject o = JObject.Parse(readContents2);
JArray a = (JArray)o["Basic"];
setsList.Add(a.ToObject<IList<Card>>());
a = (JArray)o["Debug"];
setsList.Add(a.ToObject<IList<Card>>());
我觉得这样做不对,因为每次添加集时我都必须更新它。
如果我的 classes 结构正确,下面的内容应该足以(或稍微修改的形式)处理来自 json 的所有集合,不是吗?
using (StreamReader file = File.OpenText("AllSets.json"))
{
JsonSerializer serializer = new JsonSerializer();
List<Card> myCards = (List<Card>)serializer.Deserialize(file, typeof(List<Card>));
}
尝试反序列化为字符串字典,列表:
JObject o = JObject.Parse(readContents2);
var cards = a.ToObject<IDictionary<string, IList<Card>>>();
或者只是
var cards = JsonConvert.DeserializeObject<IDictionary<string, IList<Card>>>(readContents2);
您将拥有一个字典,其中包含作为键的集合名称和作为值的卡片。
在此处检查示例:https://dotnetfiddle.net/m3rJYD
我正在使用 C# 和 NewtonSoft 框架反序列化 json。 JSON 来自 http://hearthstonejson.com/。 看起来像这样。 http://i.imgur.com/8pmxLYd.png
{"Basic":[
{"id":"GAME_004","name":"AFK","type":"Enchantment","text":"Your turns are shorter."},
{"id":"EX1_066","name":"Acidic Swamp Ooze","type":"Minion","faction":"Alliance","rarity":"Common","cost":2,"attack":3,"health":2,"text":"<b>Battlecry:</b> Destroy your opponent's weapon.","flavor":"Oozes love Flamenco. Don't ask.","artist":"Chris Rahn","collectible":true,"howToGetGold":"Unlocked at Rogue Level 57.","mechanics":["Battlecry"]},
我可以很容易地一次反序列化一个集合到我的 classes 中,但不能一次反序列化所有集合。对我来说,我不明白的问题是反序列化器会正确地为每个 属性 填充一个值,但是如果一个值存在而前面没有要填充的 属性 怎么办。
"id":"GAME_004"
很容易填入
public string id;
但是
{"Basic":[{"id":"GAME_004",
("basic") 或任何其他卡组名称不会填写任何内容,除非它有一个 属性 匹配。我假设我不需要提前知道卡组名称是什么。我应该能够将每个集合填充到一个集合中而不必知道名称或者这是错误的吗?我可以不将每个对象的开头自动分配给 class 中的 属性 而不必特别知道名称吗?
Token: StartObject
Token: PropertyName, Value: Basic
Token: StartArray
Token: StartObject
Token: PropertyName, Value: id
Token: String, Value: GAME_004
或者我必须对每个单独的集合执行以下操作吗?或者我错过了构建 classes 的步骤。
List<IList<Card>> setsList = new List<IList<Card>>();
JObject o = JObject.Parse(readContents2);
JArray a = (JArray)o["Basic"];
setsList.Add(a.ToObject<IList<Card>>());
a = (JArray)o["Debug"];
setsList.Add(a.ToObject<IList<Card>>());
我觉得这样做不对,因为每次添加集时我都必须更新它。 如果我的 classes 结构正确,下面的内容应该足以(或稍微修改的形式)处理来自 json 的所有集合,不是吗?
using (StreamReader file = File.OpenText("AllSets.json"))
{
JsonSerializer serializer = new JsonSerializer();
List<Card> myCards = (List<Card>)serializer.Deserialize(file, typeof(List<Card>));
}
尝试反序列化为字符串字典,列表:
JObject o = JObject.Parse(readContents2);
var cards = a.ToObject<IDictionary<string, IList<Card>>>();
或者只是
var cards = JsonConvert.DeserializeObject<IDictionary<string, IList<Card>>>(readContents2);
您将拥有一个字典,其中包含作为键的集合名称和作为值的卡片。
在此处检查示例:https://dotnetfiddle.net/m3rJYD