Non esiste un elemento ViewData di tipo ‘IEnumerable ‘ che ha la chiave ‘GradingId’

Sto cercando di ottenere un elenco a discesa per lavorare per gli utenti che vengono valutati. Ogni utente può avere più voti. Quindi quando creo un nuovo grado voglio un menu a discesa per specificare quale utilizzare chi riceverà il voto.

Continuo a ricevere:

Non esiste un elemento ViewData di tipo “IEnumerable” con la chiave “GradingId”.

Ho esaminato molte altre domande, ma non riesco a capire cosa devo cambiare nel mio controller, nella mia vista o nei miei modelli.

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 (Visualizza)

 @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 (modello)

 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 (modello)

 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; } } } 

In Create azione get non stai impostando ViewBag.GradingId con SelectList che causa l’errore in Visualizza:

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

Puoi evitare problemi come questo usando Viewmodel . Darin Dimitrov spiega meglio di me perché dovresti usarne uno.

Ottieni Intellisense e puoi utilizzare le versioni fortemente tipizzate degli helper Html all’interno delle tue visualizzazioni. Riceverai anche un codice di refactoring e non farai più affidamento su stringhe magiche. Inoltre, è chiaro dove le informazioni provengono da una determinata vista guardando solo il modello di vista a cui questa vista è fortemente tipizzata.

Per la tua pagina di creazione, è ansible creare un Viewmodel appropriato;

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

Utilizzando tale modello per la visualizzazione, è ansible passare le raccolte a discesa come parte del modello per la vista. In questo esempio, un object dominio è incluso come parte del modello di vista. Se hai bisogno di più controllo su questo, puoi usare le proprietà del tuo modello di dominio invece di un object dominio, che ti permetterebbe di usare annotazioni di dati. Avresti quindi bisogno di un mappatore per mappare l’object al tuo tipo di dominio.

Tutto quello che devi modificare nel controller è il metodo GET per istanziare il modello con i tuoi valori dropdown e il metodo POST per accettare il modello di visualizzazione e agire di conseguenza.

Anche se non fa parte della tua domanda, ti imbatterai in un problema completamente diverso una volta diventato operativo. Il nome dell’object ViewBag non può essere uguale al nome della proprietà. Altrimenti, il valore selezionato non verrà mai selezionato poiché il valore in ViewBag sovrascriverà il valore sul modello.

GradingIdChoices nome alla tua lista di selezione qualcosa come GradingIdChoices , non GradingId per disambiggerlo.