C#中从动态JSON获取属性名及遍历的技术问询
嘿,我来帮你梳理下这个问题的解决思路~你遇到的核心问题是:你存的dynamic变量其实是JSON数组类型(比如Newtonsoft.Json里的JArray,或者System.Text.Json里的JsonElement数组),而不是单个JSON对象。你调用GetType().GetProperties()拿到的是数组本身的属性(比如Item、Count这些),自然不是你要的对象属性名。
下面我分两种常用的JSON处理库来给你具体的解决方案,还有无需预定义模型的灵活处理方案:
方案一:使用Newtonsoft.Json(Json.NET)
如果你是用Newtonsoft.Json解析的JSON(比如JsonConvert.DeserializeObject<dynamic>(jsonString)),那你的dynamic数组里的每个元素其实是JObject类型,我们可以先从第一个元素提取所有属性名,再遍历数组用这些属性名取值:
1. 获取目标属性名列表
using Newtonsoft.Json.Linq; using System.Linq; // 先把dynamic转成JArray(更可控) var jsonArray = json as JArray; if (jsonArray == null || !jsonArray.Any()) { // 处理空数组的情况,直接返回 return; } // 从第一个JSON对象里提取所有属性名 var propertyNames = jsonArray.First() .Cast<JObject>() .SelectMany(jObj => jObj.Properties()) .Select(prop => prop.Name) .ToList();
2. 用动态属性名遍历取值
拿到属性名后,就可以遍历数组,通过属性名动态获取每个对象的对应值:
foreach (var item in jsonArray) { var jObj = item as JObject; foreach (var propName in propertyNames) { // 动态获取属性值,返回JToken,可按需转成对应类型 var value = jObj[propName]; Console.WriteLine($"{propName}: {value}"); // 示例:转成特定类型 // if (propName == "Standard_Tare_Weight") // { // var tareWeight = value.Value<decimal>(); // } } }
方案二:使用System.Text.Json(官方内置)
如果用的是.NET Core/.NET 5+的System.Text.Json解析(比如JsonSerializer.Deserialize<dynamic>(jsonString)),那dynamic数组里的元素是JsonElement类型,处理方式类似:
1. 获取目标属性名列表
using System.Text.Json; // 把dynamic转成JsonElement数组 var jsonElementArray = json as JsonElement[]; if (jsonElementArray == null || jsonElementArray.Length == 0) { return; } // 从第一个对象提取所有属性名 var propertyNames = new List<string>(); var firstObj = jsonElementArray[0]; if (firstObj.ValueKind == JsonValueKind.Object) { foreach (var prop in firstObj.EnumerateObject()) { propertyNames.Add(prop.Name); } }
2. 用动态属性名遍历取值
foreach (var item in jsonElementArray) { if (item.ValueKind == JsonValueKind.Object) { foreach (var propName in propertyNames) { if (item.TryGetProperty(propName, out JsonElement value)) { // 根据属性类型获取对应值,这里做了简单的类型适配 string outputValue = value.ValueKind switch { JsonValueKind.String => value.GetString(), JsonValueKind.Number => value.GetDecimal().ToString(), JsonValueKind.True or JsonValueKind.False => value.GetBoolean().ToString(), JsonValueKind.Null => "null", _ => value.ToString() }; Console.WriteLine($"{propName}: {outputValue}"); } } } }
无需预定义模型的灵活JSON处理方案
上面两种方式就是典型的无模型JSON处理方案,完全不需要提前定义实体类:
- Newtonsoft.Json的JObject/JArray:生态成熟,支持LINQ查询、动态修改属性,适合复杂JSON场景,处理起来很灵活。
- System.Text.Json的JsonDocument/JsonElement:官方内置,无需额外安装包,性能出色,适合.NET Core/.NET 5+的项目。
另外,你也可以用ExpandoObject来解析JSON,这样每个对象会被转成动态的ExpandoObject,既可以像普通对象一样用.访问属性,也能通过IDictionary<string, object>获取所有属性名和值:
using System.Dynamic; using Newtonsoft.Json; // 把JSON转成ExpandoObject列表 var expandoArray = JsonConvert.DeserializeObject<List<ExpandoObject>>(jsonString); foreach (var expando in expandoArray) { // 转成字典遍历属性名和值 var propDict = expando as IDictionary<string, object>; foreach (var (propName, propValue) in propDict) { Console.WriteLine($"{propName}: {propValue}"); } }
这样不管JSON结构怎么变,都能灵活处理,完全不需要预定义模型~
内容的提问来源于stack exchange,提问作者gp2gp2




