【问题标题】:can't get values in foreach from Viewbag mvc无法从 Viewbag mvc 获取 foreach 中的值
【发布时间】:2016-09-27 22:04:06
【问题描述】:

我正在尝试从 userList viewbag 中获取值。我无法找出解决方案。错误是:

System.Core.dll 中出现“Microsoft.CSharp.RuntimeBinder.RuntimeBinderException”类型的异常,但未在用户代码中处理

附加信息:“对象”不包含“名称”的定义

虽然在 ViewBag.userList 中包含我在调试时可以看到的数据(2 个对象)

@foreach (var aUser in ViewBag.userList)
{
    <tr>
        <td>@aUser.name</td>
        <td>@aUser.username</td>
        .....
        <td>@Html.ActionLink("Edit", "UserEdit","Users")</td>
        <td>@Html.ActionLink("Delete", "UserDelete", "Users")</td>
    </tr>
}

我有一个超类和一个子类

超类

public partial class user
{
    public int id { get; set; }
    public string name { get; set; }
    public string username { get; set; }
    ...
    public string user_role { get; set; }
}

子类

public class UserSub: user
{
    public string CreatedUserName { get; set; }
    public string ModifiedUserName { get; set; }
    
}

在我的控制器中,我使用 linq 从数据库中获取值并将其存储到 Viewbag.userList。我的控制器功能是

public ActionResult UserList()
{
    IEnumerable<user> users = null;
    users = dbEntities.users.ToList();
    
    if (users != null)
    {
        var userLists = (from a in users join b in users on a.created_user_id equals b.id select new { a.name, a.username, a.password, a.user_role, a.is_enable, a.is_approved, CreatedUserName = b.name, a.create_time, a.is_android, a.device_id }).ToList();
        ViewBag.userList = userLists;  
    }
    return View();
}

试过List&lt;UserSub&gt; users=ViewBag.userList....也报错

【问题讨论】:

  • 因为ViewBag.userList 是一个匿名对象的集合。您需要将数据投影到模型中(包含属性nameusernamepassword 等)。并且不要使用ViewBag - 将模型传递给视图)
  • 试过投射...但也有错误
  • 你为什么不能尝试将它作为模型 return View(userLists); 而不是在 ViewBag 中传递
  • 投到什么?你需要yourQuery.Select(x =&gt; new someModel{ .... }
  • userLists = (从 a in users 加入 b in users on a.created_user_id 等于 b.id select(c=> new UserSub {name = a.name, username = a.username, password = a .password,user_role = a.user_role,is_enable = a.is_enable,is_approved = a.is_approved,create_time = a.create_time, is_android = a.is_android, device_id = a.device_id,CreatedUserName = b.name})).ToList( );

标签: c# asp.net-mvc linq


【解决方案1】:

使用 ViewModel 在视图和控制器之间共享数据。

例如,首先创建ViewModel

public class userViewModel{       
   public int id { get; set; }
   public string name { get; set; }
   public string username { get; set; }
   public string user_role { get; set; }
   public string CreatedUserName { get; set; }
   public string ModifiedUserName { get; set; }
   ...
}

您可以将所需的所有数据放入视图模型中...然后,我建议您在模型中创建一个包含您需要的所有查询的类(您必须研究如何做),但是您可以从您的控制器获取查询(如果需要)。

好吧,编辑你的控制器函数:

public ActionResult UserList()
{
    List<userViewModel> userVM = new List<userViewModel>(); //Important! Don't return all the query, just the data that you need.
    IEnumerable<user> users = null;
    users = dbEntities.users.ToList();

    if (users != null)
    {
        var userLists = (from a in users join b in users on a.created_user_id equals b.id select new { a.name, a.username, a.password, a.user_role, a.is_enable, a.is_approved, CreatedUserName = b.name, a.create_time, a.is_android, a.device_id }).ToList(); //I'm going to suppose that your query is ok and you get all the data that you need...

        foreach (var item in userLists)
        {
             userVM.Add(new userVM(){
                userVM.name = item.name;
                userVM.username = item.username;
                userVM.user_role = item.user_role;
                .......
             });                 
        }            
    }
    return View(userVM); //return your view model
}

最后,修改你的view并调用ViewModeluserViewModel

@model Model.ViewModel.userViewModel //It depends on the namespace
//Then try something likes this...
@foreach (var aUser in Model) 
{
    <tr>
        <td>@aUser.name</td>            
        <td>@aUser.username</td>
        .....
        <td>@Html.ActionLink("Edit", "UserEdit","Users")</td>
        <td>@Html.ActionLink("Delete", "UserDelete", "Users")</td>
    </tr>
}

就是这样,改进我的答案。 ;)

【讨论】:

  • 只是一个小评论——在你对它们添加谓词(where 子句)之前,你可能不想在你的dbEntities.users 上调用ToList()——否则你会从数据库中选择所有内容并在 .NET 中进行过滤,而不是使用数据库引擎进行过滤(假设适用)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-07
  • 2016-03-10
  • 2013-09-27
  • 1970-01-01
  • 2015-11-12
相关资源
最近更新 更多