MAC地址无键名的JSON反序列化问题:如何构建反序列化类
解决动态键JSON的反序列化问题
首先先把你的JSON数据格式化一下,方便看清楚结构:
{ "nodes": { "00:00:00:00:00:00:00:9D": { "node_id": 1, "rssi": 12, "temperature": 26, "pressure": 995, "humidity": 26, "gas_resistance": 465341, "iaq": 1 } } }
问题的核心是:nodes下面的键是动态的MAC地址(不是固定的字段名,比如mac_address),所以不能直接用普通的类来映射这部分结构,必须用字典类型来处理这个动态键集合。下面分几种常用语言给出具体方案:
Python 解决方案
直接用字典处理
最简单的方式是直接把JSON反序列化为字典,然后遍历键值对:
import json # 你的JSON字符串 json_str = '''{ "nodes": { "00:00:00:00:00:00:00:9D": { "node_id": 1, "rssi": 12, "temperature": 26, "pressure": 995, "humidity": 26, "gas_resistance": 465341, "iaq": 1 } } }''' # 反序列化为字典 data = json.loads(json_str) # 遍历所有MAC地址对应的节点数据 for mac_addr, node_info in data['nodes'].items(): print(f"MAC地址: {mac_addr}") print(f"节点ID: {node_info['node_id']}") print(f"温度: {node_info['temperature']}℃")
用类封装节点数据
如果想把节点数据封装成类,用dataclass会很方便:
from dataclasses import dataclass import json @dataclass class Node: node_id: int rssi: int temperature: int pressure: int humidity: int gas_resistance: int iaq: int json_str = '''{...}''' # 同上的JSON字符串 data = json.loads(json_str) # 将字典转换为Node对象的字典 nodes_dict = {mac: Node(**node_data) for mac, node_data in data['nodes'].items()} # 使用示例 first_mac = next(iter(nodes_dict.keys())) print(f"第一个节点的IAQ值: {nodes_dict[first_mac].iaq}")
C# 解决方案
不管你用Json.NET(Newtonsoft.Json)还是System.Text.Json,核心都是用Dictionary<string, Node>来映射nodes字段。
定义实体类
public class Node { public int node_id { get; set; } public int rssi { get; set; } public int temperature { get; set; } public int pressure { get; set; } public int humidity { get; set; } public int gas_resistance { get; set; } public int iaq { get; set; } } public class Root { // 用Dictionary<string, Node>接收动态的MAC地址键 public Dictionary<string, Node> nodes { get; set; } }
用Json.NET反序列化
using Newtonsoft.Json; string json = @"{ ""nodes"": { ""00:00:00:00:00:00:00:9D"": { ""node_id"": 1, ""rssi"": 12, ""temperature"": 26, ""pressure"": 995, ""humidity"": 26, ""gas_resistance"": 465341, ""iaq"": 1 } } }"; Root root = JsonConvert.DeserializeObject<Root>(json); // 访问第一个节点数据 var firstNode = root.nodes.First(); string macAddr = firstNode.Key; Node node = firstNode.Value; Console.WriteLine($"MAC: {macAddr}, 气压: {node.pressure}hPa");
用System.Text.Json反序列化(.NET Core 3.0+)
using System.Text.Json; var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; Root root = JsonSerializer.Deserialize<Root>(json, options);
核心总结
这类动态键的JSON结构,关键就是用字典类型来替代固定字段:
- 字典的键对应动态的MAC地址(字符串类型)
- 字典的值对应节点的具体数据(用实体类或字典封装)
内容的提问来源于stack exchange,提问作者Radim Pluskal
相关产品推荐
相关产品推荐

