You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C#中从动态JSON获取属性名及遍历的技术问询

动态获取JSON对象属性名并遍历的C#解决方案

嘿,我来帮你梳理下这个问题的解决思路~你遇到的核心问题是:你存的dynamic变量其实是JSON数组类型(比如Newtonsoft.Json里的JArray,或者System.Text.Json里的JsonElement数组),而不是单个JSON对象。你调用GetType().GetProperties()拿到的是数组本身的属性(比如ItemCount这些),自然不是你要的对象属性名。

下面我分两种常用的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

火山引擎 最新活动