L’elemento del modello passato nel dizionario è di tipo .. ma questo dizionario richiede un modello di tipo

Questa domanda e la risposta wiki della comunità sono state aggiunte per aiutare a chiudere numerose domande senza risposta come discusso in questo meta post .


Ho del codice e quando viene eseguito genera un’eccezione che dice:

L’elemento del modello passato al dizionario è di tipo Bar, ma questo dizionario richiede un elemento del modello di tipo Foo

Cosa significa questo e come lo risolvo?

L’errore indica che stai navigando verso una vista il cui modello è dichiarato come typeof Foo (usando @model Foo ), ma in realtà lo hai passato un modello che è typeof Bar (si noti che il termine dizionario è usato perché un modello viene passato a la vista tramite ViewDataDictionary ).

L’errore può essere causato da

Passare il modello sbagliato da un metodo controller a una vista (o vista parziale)

Esempi comuni includono l’utilizzo di una query che crea un object anonimo (o una raccolta di oggetti anonimi) e lo passa alla vista

 var model = db.Foos.Select(x => new { ID = x.ID, Name = x.Name }; return View(model); // passes an anonymous object to a view declared with @model Foo 

o passare una raccolta di oggetti a una vista che si aspetta un singolo object

 var model = db.Foos.Where(x => x.ID == id); return View(model); // passes IEnumerable to a view declared with @model Foo 

L’errore può essere facilmente identificato in fase di compilazione dichiarando esplicitamente il tipo di modello nel controller in modo che corrisponda al modello nella vista anziché utilizzare var .

Passare il modello sbagliato da una vista a una vista parziale

Dato il seguente modello

 public class Foo { public Bar MyBar { get; set; } } 

e una vista principale dichiarata con @model Foo e una vista parziale dichiarata con @model Bar , quindi

 Foo model = db.Foos.Where(x => x.ID == id).Include(x => x.Bar).FirstOrDefault(); return View(model); 

restituirà il modello corretto alla vista principale. Tuttavia, l’eccezione verrà generata se la vista include

 @Html.Partial("_Bar") // or @{ Html.RenderPartial("_Bar"); } 

Per impostazione predefinita, il modello passato alla vista parziale è il modello dichiarato nella vista principale ed è necessario utilizzarlo

 @Html.Partial("_Bar", Model.MyBar) // or @{ Html.RenderPartial("_Bar", Model.MyBar); } 

per passare l’istanza di Bar alla vista parziale. Si noti inoltre che se il valore di MyBar è null (non è stato inizializzato), per impostazione predefinita Foo verrà passato al partial, nel qual caso, deve essere

 @Html.Partial("_Bar", new Bar()) 

Dichiarazione di un modello in un layout

Se un file di layout include una dichiarazione del modello, tutte le viste che utilizzano quel layout devono dichiarare lo stesso modello o un modello che deriva da quel modello.

Se si desidera includere l’html per un modello separato in un Layout, quindi nel Layout, usare @Html.Action(...) per chiamare un metodo [ChildActionOnly] inizializza quel modello e restituisce una vista parziale per esso.

Osservare se la vista ha il modello richiesto:

vista

 @model IEnumerable 
....

controllore

  [HttpGet] public ActionResult ListItems() { SiteStore site = new SiteStore(); site.GetSites(); IEnumerable sites = site.SitesList.Select(s => new SiteViewModel { Id = s.Id, Type = s.Type }); return PartialView("_ListItems", sites); } 

Nel mio caso, utilizzo una vista parziale ma viene eseguita in visualizzazioni normali

Questa domanda ha già un’ottima risposta, ma mi sono imbattuto nello stesso errore, in uno scenario diverso: la visualizzazione di una List in un editorampade .

Ho un modello come questo:

 public class Foo { public string FooName { get; set; } public List Bars { get; set; } } public class Bar { public string BarName { get; set; } } 

E questa è la mia opinione principale :

 @model Foo @Html.TextBoxFor(m => m.Name, new { @class = "form-control" }) @Html.EditorFor(m => m.Bars) 

E questo è il mio Bar EditorTemplate ( Bar.cshtml )

 @model List 
@foreach (var item in Model) { }

E ho ricevuto questo errore:

L’elemento del modello passato nel dizionario è di tipo ‘Bar’, ma questo dizionario richiede un elemento del modello di tipo ‘System.Collections.Generic.List`1 [Bar]


Il motivo di questo errore è che EditorFor già EditorFor iterazione List per te, quindi se passi una collezione ad esso, visualizzerà il modello di editor una volta per ogni elemento nella raccolta.

Ecco come ho risolto questo problema:

Ha portato gli stili all’esterno del modello di editor e nella vista principale :

 @model Foo @Html.TextBoxFor(m => m.Name, new { @class = "form-control" }) 
@Html.EditorFor(m => m.Bars)

E modificato EditorTemplate ( Bar.cshtml ) in questo modo:

 @model Bar