问题描述
通常,当我使用API并获取Json字符串时,我只是简单地制作一个适合该字符串的类,然后使用newton JsonConvert.DeserializeObject填充该类。
{
"attacks": {
"114862720": {
"code": "115dc2b990153c41c33d519b26cc302a","timestamp_started": 1596782220,"timestamp_ended": 1596782226,"attacker_id": 580816,"attacker_name": "chedders","attacker_faction": 32585,"attacker_factionname": "Heart of a Pirate","defender_id": 65306,"defender_name": "-Clansdancer","defender_faction": 0,"defender_factionname": null,"result": "Attacked","stealthed": 0,"respect_gain": 4.14,"chain": 3,"modifiers": {
"fairfight": 3,"war": 1,"retaliation": 1,"groupAttack": 1,"overseas": 1,"chainBonus": 1
}
},"114862829": {
"code": "8bf08c8ceb9b72f05f40235310cd822e","timestamp_started": 1596782339,"timestamp_ended": 1596782344,"defender_id": 964979,"defender_name": "brko21","respect_gain": 4.11,"chain": 4,"chainBonus": 1
}
}
}
}
攻击后的ID是每个条目唯一的ID。因此我通常为此目的建立一个类,因为ID是未知的。
任何欢迎使用该字符串反序列化的指针。
解决方法
您可以使用[JsonExtensionData]
属性。
这是官方示例:
public class DirectoryAccount
{
// normal deserialization
public string DisplayName { get; set; }
// these properties are set in OnDeserialized
public string UserName { get; set; }
public string Domain { get; set; }
[JsonExtensionData]
private IDictionary<string,JToken> _additionalData;
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
// SAMAccountName is not deserialized to any property
// and so it is added to the extension data dictionary
string samAccountName = (string)_additionalData["SAMAccountName"];
Domain = samAccountName.Split('\\')[0];
UserName = samAccountName.Split('\\')[1];
}
public DirectoryAccount()
{
_additionalData = new Dictionary<string,JToken>();
}
}
因此,在您的OnDeserializing
方法中,您可以从字典中获取值并将其添加到适当的字段中/并将其投射到对象列表等中。
这将反序列化为Dictionary<string,Attack>
。其中,Attack是一种类型,您可以在JSON文档中使用每个对象内的所有属性对其进行定义。
此示例假设您正在使用NewtonSofts JSON库:
var attacks = JsonConvert.DeserializeObject<Dictionary<string,Attack>>(jsonString);
public class Attack {
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("timestamp_started")]
public long TimestampStarted { get; set; }
[JsonProperty("timestamp_ended")]
public long TimestampEnded { get; set; }
[JsonProperty("attacker_id")]
public int AttackerId { get; set; }
[JsonProperty("attacker_name")]
public string AttackerName { get; set; }
[JsonProperty("attacker_faction")]
public int AttackerFaction { get; set; }
[JsonProperty("attacker_factionname")]
public string AttackerFactionName { get; set; }
[JsonProperty("defender_id")]
public int DefenderId { get; set; }
[JsonProperty("defender_name")]
public string DefenderName { get; set; }
[JsonProperty("defender_faction")]
public int DefenderFaction { get; set; }
[JsonProperty("defender_factionname")]
public string DefenderFactionName { get; set; }
[JsonProperty("result")]
public string Result { get; set; }
[JsonProperty("stealthed")]
public int Stealthed { get; set; }
[JsonProperty("respect_gain")]
public decimal RespectGain { get; set; }
[JsonProperty("chain")]
public int Chain { get; set; }
[JsonProperty("modifiers")]
public Dictionary<string,int> Modifiers { get; set; }
}
这将导致针对强类型字段集的标识符集合。
var allAttacksByFaction = attacks.Where(x => x.Value.AttackerFaction == 1234);
var singleAttack = attacks.Single(x => x.Key == "<value of attack identifier>");
,
尝试使用此json转换器。
class AttacksConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Attacks[]);
}
public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
{
JObject attacks = serializer.Deserialize<JObject>(reader);
Dictionary<string,AttackDetails> result = new Dictionary<string,AttackDetails>();
foreach (JProperty property in attacks.Properties())
{
string attackKey = property.Name;
Attacks attackValue = property.Value.ToObject<Attacks>();
result.Add(attackKey,new AttackDetails()
{
Code = attackValue.Code
});
}
return result;
}
public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
完整代码可在此处找到:https://github.com/tmutton/StackOverflowQuestion63544325