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

C#中LINQ语句报Unable to cast object of type转换异常如何解决

问题描述

执行到代码行var columnNames =时抛出以下类型转换异常:

System.InvalidCastException: 'Unable to cast object of type 'System.Object' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'.'

对应后端业务代码如下:

public JsonResult SaveData(List<object> customers)
{
    DataTable dt = new DataTable();
    
    var columnNames = ((Dictionary<string, object>)customers[0]).Select(x => x.Key).ToList();
    for (int i = 0; i < columnNames.Count(); i++)
    {
        dt.Columns.Add(columnNames[i]);
    }
    foreach (Dictionary<string, object> customer in customers)
    {
        DataRow dr = dt.NewRow();
        for (int i = 0; i < columnNames.Count(); i++)
        {
            dr[columnNames[i]] = customer[columnNames[i]];
        }
        dt.Rows.Add(dr);
    }

    return Json('1');
}

前端传递的参数在浏览器控制台打印格式如下:

0 : {Id: "1", Name: "abc", Country: "uk", __rowNum__: 1}
1: {Id: "2", Name: "kala", Country: "us", __rowNum__: 2}
2: {Id: "3", Name: "Has", Country: "IN", __rowNum__: 3}
问题根因

把接口参数定义成List<object>后,ASP.NET 的模型绑定器反序列化前端传来的JSON对象时,不会自动把集合里的每个JSON对象转成Dictionary<string,object>:根据项目用的序列化组件不同,集合元素实际运行时类型是System.Text.Json.JsonElement(.NET Core/5+ 默认序列化配置)或者Newtonsoft.Json.Linq.JObject(.NET Framework 或手动切换序列化组件为Newtonsoft.Json的场景),直接硬转Dictionary必然抛出类型转换异常。

排查&解决方法
  • 第一步先确认实际类型:在报错行前打断点,调试时查看customers[0].GetType().FullName,就能拿到元素的真实运行时类型,避免盲目强转。
  • 最优方案:直接修改接口参数类型为List<Dictionary<string, object>>,让模型绑定器自动完成反序列化,无需手动强转。修改后的可运行代码如下:
public JsonResult SaveData(List<Dictionary<string, object>> customers)
{
    DataTable dt = new DataTable();
    
    // 无需强转,直接取Key作为DataTable列名
    var columnNames = customers[0].Select(x => x.Key).ToList();
    for (int i = 0; i < columnNames.Count; i++)
    {
        dt.Columns.Add(columnNames[i]);
    }
    foreach (var customer in customers)
    {
        DataRow dr = dt.NewRow();
        for (int i = 0; i < columnNames.Count; i++)
        {
            dr[columnNames[i]] = customer[columnNames[i]];
        }
        dt.Rows.Add(dr);
    }

    // 注意C#中字符串用双引号包裹,单引号代表char类型,原写法会触发编译错误
    return Json("1");
}
  • 兼容方案:如果因为业务逻辑限制不能修改参数类型,就根据项目实际使用的序列化组件做对应转换:
    • 使用System.Text.Json的场景:
      var firstCustomer = JsonSerializer.Deserialize<Dictionary<string, object>>(customers[0]!.ToString()!);
      var columnNames = firstCustomer.Select(x => x.Key).ToList();
      // 遍历集合时,每个元素都调用JsonSerializer反序列化为Dictionary<string,object>再处理即可
      
    • 使用Newtonsoft.Json的场景:
      var firstCustomer = (customers[0] as JObject)?.ToObject<Dictionary<string, object>>();
      var columnNames = firstCustomer.Select(x => x.Key).ToList();
      // 遍历集合时,每个JObject元素调用ToObject<Dictionary<string,object>>()转换后再处理即可
      

内容的提问来源于stack exchange,提问作者atc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:45:43