【发布时间】:2021-09-17 13:43:31
【问题描述】:
我的应用程序接收到包含 Dictionary<string,string> 作为属性之一的 Kafka 消息,它的值可能是一个嵌套的(但是是动态的)json 字符串,我需要遍历这个未知的 json。我正在努力寻找一个逻辑,甚至是最好的数据结构来进行这个迭代。
字典示例(模拟数据):
//could have complex nested json string as value
"reward":"{
'xp':'200',
'gp':'150',
'loot':'{
'item':'sword',
'rarity': 'low'
}'
}",
"achievement":"win_match"
// while other messages might be simple
"type":"generic_xp",
"percent":"100",
"status":"complete"
真实消息的序列化版本:
"{\"player_stats\":\"{\\\"assist\\\":0,\\\"deaths\\\":0,\\\"kills\\\":0,\\\"team_index\\\":2}\",\"round_attr\":\"{\\\"max_player_count\\\":4,\\\"rdur\\\":0,\\\"round\\\":1,\\\"team_player_count\\\":{\\\"team_1\\\":1,\\\"team_2\\\":0},\\\"team_score\\\":0}\",\"custom\":\"{\\\"armor\\\":\\\"armor_pickup_lv2\\\",\\\"balance\\\":550,\\\"helmet\\\":\\\"helmet_pickup_lv2\\\",\\\"misc\\\":[{\\\"count\\\":48,\\\"item_id\\\":\\\"shotgun\\\"},{\\\"count\\\":120,\\\"item_id\\\":\\\"bullet\\\"},{\\\"count\\\":2,\\\"item_id\\\":\\\"health_pickup_combo_small\\\"},{\\\"count\\\":2,\\\"item_id\\\":\\\"health_pickup_health_small\\\"}],\\\"weapon_1\\\":\\\"mp_weapon_semipistol\\\",\\\"weapon_2\\\":\\\"mp_weapon_shotgun_pistol\\\"}\",\"gdur\":\"0\"}"
更复杂的
- 创建模型类不是一个选项,因为这个 json 是完全动态的
- 无法对字典进行扁平化,因为 json 可能具有重复的键名,但在不同的层次结构下
- 我无法请求更改 Kafka 消息
我要做什么
最终用户将定义我需要检查是否找到匹配项的规则。例如,规则可以是reward.xp == 200 或reward.loot.rarity == high 或status == complete。这些规则将由用户定义,因此不能硬编码,但是我可以决定使用数据结构来保存它们。因此,对于每条 Kafka 消息,我必须遍历该字典并尝试找到与规则匹配的内容。
我的尝试
我尝试过JsonConvert.Deserialize 到object、dynamic、ExpandoObject,但没有一个可以处理嵌套的 json 层次结构。他们刚刚答对了第一级。与JObject.Parse 的结果相同。
【问题讨论】:
-
如果 json 字符串是动态的,为什么要坚持反序列化为具体类型?只持有 jsonobject 并获取您想要的任何数据怎么样?既然你标记了.net core,你会使用内置的json库吗?
-
json.net 应该使用 JObject.Parse 处理这个问题。要进行迭代,您需要对树中的节点进行递归访问。如果需要,您可以将其展平为列表 - 使用节点的完整路径作为列表中的键(例如
reward.loot.rarity)。 -
“重复的键名,但在不同的层次结构下”是什么意思?你能举个例子吗?
-
@BrianRogers 例如
reward可以在根目录中,如上例所示,但也可能在achievement.reward下。所以如果我把结构弄平,我会得到重复键的错误。 -
@andrew
JObject.Parse只正确解析了第一级。在奖励示例中,我正确地得到了孩子xp和gp,但是对于loot,它没有孩子,而是保留了字符串值。所以在这个例子中,loot属性变成了一个字符串属性,它的值是一个类似于序列化示例的转义字符串
标签: c# .net-core json.net dynamic-programming