没有具有键 'GradingId' 的类型 'IEnumerable<SelectListItem>' 的 ViewData 项
There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'GradingId'
我正在尝试获取一个下拉列表以供正在评分的用户使用。每个用户可以有多个评分。因此,当我创建新成绩时,我想要一个下拉列表来指定将获得成绩的用户。
我不断得到:
There is no ViewData item of type 'IEnumerable' that has the key '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
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="editor-label">
@Html.LabelFor(model => model.User.CodeName, "User Name")
</div>
<div class="editor-field">
@Html.DropDownList("GradingId", String.Empty)
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
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<Grading> UserGradings { get; set; }
}
}
在 Create
get 操作中,您没有使用 SelectList 设置 ViewBag.GradingId
,这导致视图中出现错误:
public ActionResult Create()
{
ViewBag.GradingId = new SelectList(db.Gradings, "GradingId", "CodeName");
return View();
}
你可以通过使用一个 Viewmodel. Darin Dimitrov explains better 来避免这样的问题,而不是为什么你应该使用一个。
You get Intellisense and you can use the strongly typed versions of the Html helpers inside your views. You also get a refactor friendly code and no longer rely on magic strings. Also it is clear where the information is coming from to a given view by only looking at the view model that this view is strongly typed to.
对于您的创建页面,可以创建合适的Viewmodel;
public class CreateGradeViewModel {
Grading Grading { get; set; }
IEnumerable<Grading> Gradings { get; set; }
}
将该模型用于您的视图,然后您可以将下拉集合作为视图模型的一部分进行传递。在此示例中,域对象作为视图模型的一部分包含在内。如果您需要对此进行更多控制,您可以使用域模型的属性而不是域对象,这将允许您使用数据注释。然后您需要一个映射器将对象映射回您的域类型。
您需要在控制器中进行的所有更改是 GET
方法以使用您的下拉值实例化模型,以及 POST
方法以接受视图模型并对其进行相应操作。
虽然这不是您问题的一部分,但一旦您开始执行此操作,您将 运行 遇到一个完全不同的问题。您的 ViewBag
项目的名称不能与您的 属性 的名称相同。否则,selected 值永远不会被 selected,因为 ViewBag
中的值将覆盖模型上的值。
将您的 select 列表命名为 GradingIdChoices
,而不是 GradingId
以消除歧义。
我正在尝试获取一个下拉列表以供正在评分的用户使用。每个用户可以有多个评分。因此,当我创建新成绩时,我想要一个下拉列表来指定将获得成绩的用户。
我不断得到:
There is no ViewData item of type 'IEnumerable' that has the key '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
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="editor-label">
@Html.LabelFor(model => model.User.CodeName, "User Name")
</div>
<div class="editor-field">
@Html.DropDownList("GradingId", String.Empty)
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
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<Grading> UserGradings { get; set; }
}
}
在 Create
get 操作中,您没有使用 SelectList 设置 ViewBag.GradingId
,这导致视图中出现错误:
public ActionResult Create()
{
ViewBag.GradingId = new SelectList(db.Gradings, "GradingId", "CodeName");
return View();
}
你可以通过使用一个 Viewmodel. Darin Dimitrov explains better 来避免这样的问题,而不是为什么你应该使用一个。
You get Intellisense and you can use the strongly typed versions of the Html helpers inside your views. You also get a refactor friendly code and no longer rely on magic strings. Also it is clear where the information is coming from to a given view by only looking at the view model that this view is strongly typed to.
对于您的创建页面,可以创建合适的Viewmodel;
public class CreateGradeViewModel {
Grading Grading { get; set; }
IEnumerable<Grading> Gradings { get; set; }
}
将该模型用于您的视图,然后您可以将下拉集合作为视图模型的一部分进行传递。在此示例中,域对象作为视图模型的一部分包含在内。如果您需要对此进行更多控制,您可以使用域模型的属性而不是域对象,这将允许您使用数据注释。然后您需要一个映射器将对象映射回您的域类型。
您需要在控制器中进行的所有更改是 GET
方法以使用您的下拉值实例化模型,以及 POST
方法以接受视图模型并对其进行相应操作。
虽然这不是您问题的一部分,但一旦您开始执行此操作,您将 运行 遇到一个完全不同的问题。您的 ViewBag
项目的名称不能与您的 属性 的名称相同。否则,selected 值永远不会被 selected,因为 ViewBag
中的值将覆盖模型上的值。
将您的 select 列表命名为 GradingIdChoices
,而不是 GradingId
以消除歧义。