You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JSON解析为C#并正确取数?我的反序列化方法为何失效

解决JSON反序列化为C#类型的常见问题

嘿,我来帮你把这个JSON反序列化的问题理清楚!你遇到的错误其实是类型不匹配导致的,咱们一步步拆解解决:

先搞懂你之前踩的两个坑

  1. 直接反序列化数组时的InvalidCast异常
    你一开始的JSON是[{...}, {...}]这种根级数组,但你用了反序列化成Dictionary的方法——这就好比把一箱苹果硬塞进橘子盒子,肯定装不下!因为JSON数组对应C#里的List<T>或数组T[],而Dictionary是对应JSON键值对对象的,类型完全不匹配,所以会抛出无法转换的异常。

  2. 修改JSON后拿到字典但没法访问数组
    你改成{"array": "[{...}, {...}]"}后,异常消失了,但这里有个隐藏问题:你把数组变成了字符串(注意外面的引号),而不是原生的JSON数组。所以反序列化后,字典里的"array"对应的值其实是一串文本,不是可直接遍历的数组。要解决这个,你应该把JSON改成{"array": [{...}, {...}]}(去掉数组外面的引号,让它成为真正的JSON数组)。

正确的反序列化方法(分两种场景)

场景1:JSON根是数组([{...}, {...}])

这种情况最直接的方式是定义一个对应数组元素的实体类,然后反序列化成List<实体类>:

假设你的JSON数组元素是用户信息,先定义类:

public class User
{
    // 属性名要和JSON里的键名对应,也可以用特性指定映射
    public string Username { get; set; }
    public int Score { get; set; }
}

用.NET自带的System.Text.Json(.NET Core/.NET 5+可用)反序列化:

string jsonArray = @"[{""Username"":""Alex"",""Score"":95},{""Username"":""Mia"",""Score"":88}]";
List<User> userList = JsonSerializer.Deserialize<List<User>>(jsonArray);

// 访问数据示例
foreach (var user in userList)
{
    Console.WriteLine($"{user.Username} 的分数是 {user.Score}");
}

如果用Newtonsoft.Json(Json.NET),代码更简洁:

List<User> userList = JsonConvert.DeserializeObject<List<User>>(jsonArray);

场景2:JSON根是包含数组的对象({"array": [{...}, {...}]})

这种情况有两种处理方式:

方式1:定义根实体类(推荐,类型安全)

public class RootData
{
    // 属性名要和JSON里的键名对应,比如这里的"array"
    public List<User> Array { get; set; }
}

然后反序列化:

string jsonRoot = @"{""array"": [{""Username"":""Alex"",""Score"":95},{""Username"":""Mia"",""Score"":88}]}";
RootData root = JsonSerializer.Deserialize<RootData>(jsonRoot);

// 访问数组里的数据
foreach (var user in root.Array)
{
    Console.WriteLine($"{user.Username} 的分数是 {user.Score}");
}

方式2:用Dictionary(适合临时快速处理)

如果你不想定义类,可以直接反序列化成Dictionary<string, List<User>>:

var dataDict = JsonSerializer.Deserialize<Dictionary<string, List<User>>>(jsonRoot);
List<User> userList = dataDict["array"];
// 后续访问和场景1一样

如果不知道JSON结构,想动态访问数据

如果你不确定JSON的具体结构,可以用JsonElement(System.Text.Json)或者dynamic类型(Newtonsoft.Json支持更好):

用JsonElement(类型安全)

string jsonArray = @"[{""Username"":""Alex"",""Score"":95},{""Username"":""Mia"",""Score"":88}]";
JsonElement root = JsonSerializer.Deserialize<JsonElement>(jsonArray);

if (root.ValueKind == JsonValueKind.Array)
{
    foreach (var element in root.EnumerateArray())
    {
        string username = element.GetProperty("Username").GetString();
        int score = element.GetProperty("Score").GetInt32();
        Console.WriteLine($"{username} 的分数是 {score}");
    }
}

用dynamic(快速但无类型检查)

dynamic userList = JsonConvert.DeserializeObject(jsonArray);
foreach (var user in userList)
{
    Console.WriteLine($"{user.Username} 的分数是 {user.Score}");
}

总结核心要点

  • JSON数组对应C#的List<T>或T[],JSON键值对对象对应Dictionary<K,V>或自定义实体类
  • 不要把JSON数组转换成字符串存入JSON,要保持原生的数组结构
  • 优先用实体类反序列化,类型更安全,代码可读性更高

内容的提问来源于stack exchange,提问作者Александр Копаевич

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:35:37