O item de modelo passado para o dictionary é do tipo .. mas este dictionary requer um item de modelo do tipo

Essa pergunta e a resposta do wiki da comunidade foram adicionadas para auxiliar no fechamento de inúmeras perguntas não respondidas, conforme discutido neste meta-post .


Eu tenho algum código e quando ele é executado, ele lança uma exceção dizendo:

O item de modelo passado para o dictionary é do tipo Barra, mas este dictionary requer um item de modelo do tipo Foo

O que isso significa e como faço para corrigir isso?

O erro significa que você está navegando para uma view cujo modelo é declarado como typeof Foo (usando @model Foo ), mas você realmente passou um modelo que é typeof Bar (note que o termo dictionary é usado porque um modelo é passado para a vista através de um ViewDataDictionary ).

O erro pode ser causado por

Passando o modelo errado de um método do controlador para uma visão (ou visão parcial)

Exemplos comuns incluem o uso de uma consulta que cria um object anônimo (ou coleção de objects anônimos) e passa para a exibição

 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 

ou passando uma coleção de objects para uma visão que espera um único object

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

O erro pode ser facilmente identificado em tempo de compilation declarando explicitamente o tipo de modelo no controlador para corresponder ao modelo na visão, em vez de usar var .

Passando o modelo errado de uma visão para uma visão parcial

Dado o seguinte modelo

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

e uma visão principal declarada com @model Foo e uma visão parcial declarada com @model Bar , então

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

retornará o modelo correto para a visualização principal. No entanto, a exceção será lançada se a exibição include

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

Por padrão, o modelo passado para a visão parcial é o modelo declarado na visão principal e você precisa usar

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

para passar a instância de Bar para a vista parcial. Note também que se o valor de MyBar for null (não foi inicializado), então por padrão Foo será passado para o partial, caso em que, ele precisa ser

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

Declarando um modelo em um layout

Se um arquivo de layout include uma declaração de modelo, todas as visualizações que usam esse layout deverão declarar o mesmo modelo ou um modelo derivado desse modelo.

Se você quiser include o html para um modelo separado em um Layout, então no Layout, use @Html.Action(...) para chamar um método [ChildActionOnly] que inicializa esse modelo e retorna uma visão parcial para ele.

Observe se a visão tem o modelo requerido:

Visão

 @model IEnumerable 
....

Controlador

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

No meu caso eu uso uma visão parcial, mas é executado em vistas normais

Esta questão já tem uma ótima resposta, mas eu me deparei com o mesmo erro, em um cenário diferente: exibindo uma List em um EditorTemplate .

Eu tenho um modelo como este:

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

E esta é minha visão principal :

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

E este é o meu Bar EditorTemplate ( Bar.cshtml )

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

E eu recebi este erro:

O item de modelo passado para o dictionary é do tipo ‘Barra’, mas este dictionary requer um item de modelo do tipo ‘System.Collections.Generic.List`1 [Bar]


O motivo desse erro é que o EditorFor já itera a List para você, portanto, se você passar uma coleção para ela, ela exibirá o modelo do editor uma vez para cada item da coleção.

Foi assim que consertei esse problema:

Trouxe os estilos fora do modelo do editor e para a visualização principal :

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

E mudou o EditorTemplate ( Bar.cshtml ) para isso:

 @model Bar