ASP.NET MVC将列表列表传递给ViewBag

时间:2017-01-21 19:13:37

标签: c# asp.net-mvc razor

我有一个定义为的实体:

public class Skill
{
    public enum Level { Begginer, Intermediate, Advanced }
    public int Id { get; set; }
    [Display(Name ="Skill Group")]
    public string SkillGroup { get; set; }
    [Display(Name ="Skill Name")]
    public string Name { get; set; }
    [Display(Name ="Level")]
    public Level SkillLevel { get; set; }
    public virtual ICollection<Certificate> Certificates { get; set; }

}

在我的控制器中,我试图通过类的SkillGroup属性对所有技能进行分组

        public async Task<ActionResult> Index()
    {


        var groupedSkills = (from s in db.Skills
                             group s by s.SkillGroup).ToList();
        ViewBag.GroupedSkills = groupedSkills;                   
        return View();
    }

当我在View中试图处理这个时,这部分完美地运行了:

@foreach (var skillGroup in ViewBag.GroupedSkills)
{
    <h1>@skillGroup.Key</h1>
    foreach (var item in skillGroup)
    {
        <h2>@item.Name - @item.SkillLevel </h2>
    }

}

我收到错误说:

'object' does not contain a definition for 'Key'

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'Key'

Source Error: 


Line 46: @foreach (var skillGroup in ViewBag.GroupedSkills)
Line 47: {
Line 48:     <h1>@skillGroup.Key</h1>
Line 49:     foreach (var item in skillGroup)
Line 50:     {

但是当我调试时我可以清楚地看到skillGroup列表中的属性Key我需要以某种方式投射吗?我是否需要使技能组成为非同义类型? ScreenShot of the watch for the Variable

1 个答案:

答案 0 :(得分:2)

您可以通过以下方式解决此问题。

LINQ查询的组结果将是动态的,并且在视图中访问时,每个项目都被视为对象。这就是你看到错误的原因。 对此的解决方案是将LINQ查询的组结果转换为字典,如下所示。

var groupedSkills = (from s in db.Skills group s by s.SkillGroup).ToDictionary(x => x.Key, x => x.ToList());
ViewBag.GroupedSkills = groupedSkills;

字典现在是KeyValuePair对象的集合,其中Key是SkillGroup,Value是Skills列表。 您可以将其值呈现如下。

@foreach (var skillGroup in ViewBag.GroupedSkills)
{
    <h1>@skillGroup.Key</h1>
    foreach (var item in skillGroup.Value)
    {
        <h2>@item.Name - @item.SkillLevel </h2>
    }
}