如何在C#中将JSON元素的键值对存入字典
解决方案与代码评估
先修正你的JSON格式问题
你补充尝试里的JSON是无效格式,正确的结构应该是外层一个对象,包含meta和target两个键,示例如下:
{ "meta": { "limit": 100, "offset": 0, "count": 1, "total": 1 }, "target": [ { "open": 173.99, "high": 175.46, "low": 172.675, "last": 175.38, "close": 173.66, "volume": 607334.0, "date": "2023-10-05T21:00:00+02:00", "symbol": "AAPL", "exchange": "IEXG" } ] }
错误的JSON格式是你反序列化失败的核心原因。
基于你已有的JObject加载代码的后续步骤
你已经用JObject.Parse加载了JSON,接下来直接定位target节点,再转换为字典即可:
情况1:target是单个对象
如果target是单个键值对对象而非数组:
JObject targetObj = jsonObj["target"] as JObject; Dictionary<string, object> targetDict = targetObj.ToObject<Dictionary<string, object>>();
情况2:target是对象数组(如你示例中的结构)
如果target是数组,先取数组内的第一个对象再转字典:
JArray targetArray = jsonObj["target"] as JArray; JObject firstTargetObj = targetArray.First() as JObject; Dictionary<string, object> targetDict = firstTargetObj.ToObject<Dictionary<string, object>>();
若需要将数组内所有对象转为字典列表:
List<Dictionary<string, object>> targetDictList = targetArray.ToObject<List<Dictionary<string, object>>>();
对你现有可行代码的评估
你的可行代码逻辑通顺,但存在几个优化点:
- 代码中的
jsonObj["data"]应为笔误,实际应对应jsonObj["target"],否则与你描述的结构不符。 - 手动遍历
JProperty转字典的方式可行,但Newtonsoft.Json内置的ToObject<T>()方法无需手动遍历,代码更简洁且性能更优(内部是经过优化的序列化逻辑)。 - 若目标值不一定是字符串,使用
Dictionary<string, object>比Dictionary<string, string>更灵活,能保留原始数据类型(如数字、日期);若确实需要全部转为字符串,直接用ToObject<Dictionary<string, string>>()即可,无需手动调用ToString()。
更高效的完整示例(结合异步HttpClient)
你的HttpClient代码使用.Result会导致线程阻塞,建议改用异步await模式,同时整合JSON处理:
using System; using System.Collections.Generic; using System.Net.Http; using Newtonsoft.Json.Linq; class Program { static async System.Threading.Tasks.Task Main(string[] args) { string address = "你的API地址"; using (HttpClient client = new HttpClient()) { HttpResponseMessage message = await client.GetAsync(address); message.EnsureSuccessStatusCode(); // 确保请求成功 string jsonData = await message.Content.ReadAsStringAsync(); JObject jsonObj = JObject.Parse(jsonData); // 处理target数组中的第一个对象转字典 JArray targetArray = jsonObj["target"] as JArray; if (targetArray != null && targetArray.Count > 0) { Dictionary<string, object> targetDict = targetArray.First().ToObject<Dictionary<string, object>>(); // 此处可使用targetDict foreach (var kvp in targetDict) { Console.WriteLine($"{kvp.Key}: {kvp.Value} ({kvp.Value.GetType()})"); } } } } }
关于反序列化方法的适用性
虽然你不确定目标数据的精确结构,但只要target节点下是键值对结构,就可以用ToObject<Dictionary<...>>()来反序列化,这比手动遍历更高效简洁。如果target结构完全不确定,字典方式是最适配的方案,无需提前定义实体类。
内容的提问来源于stack exchange,提问作者Douar Gwenn
相关产品推荐
相关产品推荐

