没有类型为’IEnumerable ‘的ViewData项具有键’GradingId’

我试图让一个下拉列表适用于正在评分的用户。 每个用户可以有多个评分。 因此,当我创建一个新的成绩时,我想要一个下拉列表来指定哪个用户将获得成绩。

我一直在:

没有类型为’IEnumerable’的ViewData项具有键’GradingId’。

我已经看了很多其他问题,但我无法解决我需要在控制器,视图或模型中更改的内容。

GradingController.cs

public ActionResult Create() { return View(); } // POST: Gradings/Create [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "GradingId,Eye,Cheek,Mouth,RestSymmetryTotal,RestSymmetryScore,VolForeheadWrinkle,VolGentleEyeClosure,VolOpenMouthSmile,VolSnarl,VolLipPucker,VolSymmetryTotal,VolSymmetryScore,SynForeheadWrinkle,SynGentleEyeClosure,SynOpenMouthSmile,SynSnarl,SynLipPucker,SynkinesisScore,CompositeScore")] Grading grading) { if (ModelState.IsValid) { grading.GradeDate = DateTime.Now; db.Gradings.Add(grading); db.SaveChanges(); return RedirectToAction("Index"); } ViewBag.GradingId = new SelectList(db.Gradings, "GradingId", "CodeName"); return View(grading); } // GET: Gradings/Edit/5 public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Grading grading = db.Gradings.Find(id); if (grading == null) { return HttpNotFound(); } ViewBag.GradingId = new SelectList(db.Gradings, "GradingId", "CodeName"); return View(grading); } // POST: Gradings/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "GradingId,Eye,Cheek,Mouth,RestSymmetryTotal,RestSymmetryScore,VolForeheadWrinkle,VolGentleEyeClosure,VolOpenMouthSmile,VolSnarl,VolLipPucker,VolSymmetryTotal,VolSymmetryScore,SynForeheadWrinkle,SynGentleEyeClosure,SynOpenMouthSmile,SynSnarl,SynLipPucker,SynkinesisScore,CompositeScore")] Grading grading) { if (ModelState.IsValid) { db.Entry(grading).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } ViewBag.GradingId = new SelectList(db.Gradings, "GradingId", "CodeName"); return View(grading); } 

Create.cshtml(查看)

 @model FaceToFace.Model.Grading 

Create

@using (Html.BeginForm()) { @Html.AntiForgeryToken()
@Html.LabelFor(model => model.User.CodeName, "User Name")
@Html.DropDownList("GradingId", String.Empty)
}

grading.cs(模型)

 namespace FaceToFace.Model { using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity.Spatial; [Table("Grading")] public partial class Grading { public int? User_UserID { get; set; } public virtual User User { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.None)] public int GradingId { get; set; } public DateTime GradeDate { get; set; } public DateTime GradeEditDate { get; set; } } } 

User.cs(型号)

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FaceToFace.Model { public class User { public virtual ICollection UserGradings { get; set; } } } 

Create get action中,您没有使用SelectList设置ViewBag.GradingId ,这会导致View中的错误:

 public ActionResult Create() { ViewBag.GradingId = new SelectList(db.Gradings, "GradingId", "CodeName"); return View(); } 

您可以使用Viewmodel来避免此类问题。 Darin Dimitrov比我更好地解释了为什么要使用它。

您可以获得Intellisense,并且可以在视图中使用强类型的Html助手。 您还可以获得重构友好代码,不再依赖魔术字符串。 此外,通过仅查看此视图​​强类型化的视图模型,可以清楚地将信息传递到给定视图。

对于您的创建页面,可以创建适当的Viewmodel;

 public class CreateGradeViewModel { Grading Grading { get; set; } IEnumerable Gradings { get; set; } } 

将该模型用于视图,然后可以将下拉集合作为视图模型的一部分传递。 在此示例中,域对象作为视图模型的一部分包含在内。 如果您需要对此进行更多控制,则可以使用域模型的属性而不是域对象,这样您就可以使用数据注释。 然后,您需要一个映射器将对象映射回您的域类型。

您需要在控制器中进行更改的是使用下拉值实例化模型的GET方法,以及接受视图模型并相应地对其进行操作的POST方法。

虽然这不是你问题的一部分,但是一旦你开始运作,你就会遇到一个完全不同的问题。 ViewBag项的名称不能与您的属性名称相同。 否则,将永远不会选择所选值, ViewBag的值将覆盖模型上的值。

将您的选择列表GradingIdGradingIdChoices ,而不是GradingId来消除歧义。