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

如何通过ViewBag传递查询列表?遇RuntimeBinderException异常

解决ViewBag传递匿名类列表时displayName无法访问的错误

兄弟,你踩了ASP.NET MVC里匿名类的一个常见坑——匿名类是internal访问修饰符,而MVC的视图会被编译成独立的程序集,根本没法跨程序集访问internal类型的成员,所以视图里的dynamic类型找不到displayName属性才报这个错。

下面给你几个实用的解决方案,按推荐程度排序:


1. 创建强类型ViewModel(最推荐,规范且易维护)

这是企业项目里的标准做法,类型安全还方便后续扩展:

首先在项目里加个ViewModel类:

public class EmployeeNameViewModel
{
    public string DisplayName { get; set; }
}

然后把查询里的匿名类换成这个ViewModel:

var query = (from employee in db.LKEmployeeDatas
             join transaction in db.AssetTransactions on employee.SamAccountName equals transaction.SamAccountName
             select new EmployeeNameViewModel 
             { 
                 DisplayName = employee.SamAccountName 
             }).ToList();

// 要么丢ViewBag,要么直接用强类型视图更规范
ViewBag.query = query;

视图里这样访问(最好做个类型转换确保安全):

@{ 
    var employeeList = ViewBag.query as List<EmployeeNameViewModel>;
    if (employeeList != null)
    {
        foreach (var emp in employeeList) 
        { 
            @emp.DisplayName 
        }
    }
}

更优的做法是用强类型视图,直接把列表作为视图模型传递:

// 控制器里直接传模型
return View(query);

视图顶部指定模型:

@model List<EmployeeNameViewModel>

@foreach (var emp in Model)
{
    @emp.DisplayName
}

2. 用Tuple快速解决(临时场景首选)

如果只是临时需求,不想新建类,Tuple是个快速选项:

控制器里修改查询:

var query = (from employee in db.LKEmployeeDatas
             join transaction in db.AssetTransactions on employee.SamAccountName equals transaction.SamAccountName
             select Tuple.Create(employee.SamAccountName)).ToList();

ViewBag.query = query;

视图里访问Item1就行:

@{ 
    foreach (var k in ViewBag.query) 
    { 
        @k.Item1 
    } 
}

3. 转成ExpandoObject(不推荐,类型不安全)

这种方式适合极简单的临时场景,缺点是完全没有类型检查:

控制器里把匿名类转成ExpandoObject:

var query = (from employee in db.LKEmployeeDatas
             join transaction in db.AssetTransactions on employee.SamAccountName equals transaction.SamAccountName
             select new { displayName = employee.SamAccountName })
             .Select(x => 
             {
                 dynamic expando = new ExpandoObject();
                 var dict = (IDictionary<string, object>)expando;
                 dict["displayName"] = x.displayName;
                 return expando;
             }).ToList();

ViewBag.query = query;

视图里就能正常用@k.displayName了,但这种方式后期维护容易出问题,不建议在正式项目里用。


总的来说,优先用方案1的强类型ViewModel,代码更健壮也更符合MVC的设计思想。

内容的提问来源于stack exchange,提问作者Rasindu De Alwis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:10:22