Esta pregunta y la respuesta de la wiki de la comunidad se han agregado para ayudar a cerrar numerosas preguntas sin respuesta como se analiza en esta meta publicación .
Tengo algo de código y cuando se ejecuta, lanza una excepción que dice:
El elemento de modelo pasado al diccionario es de tipo Bar, pero este diccionario requiere un elemento de modelo de tipo Foo
¿Qué significa esto y cómo lo soluciono?
c#
asp.net-mvc
Comunidad
fuente
fuente
return View
lugar de,return PartialView
por lo que es algo para verificarRespuestas:
El error significa que está navegando a una vista cuyo modelo se declara como typeof
Foo
(al usar@model Foo
), pero en realidad le pasó un modelo que es typeofBar
(tenga en cuenta que el término diccionario se usa porque un modelo se pasa a la vista a través de aViewDataDictionary
) .El error puede deberse a
Pasar el modelo incorrecto de un método de controlador a una vista (o vista parcial)
Los ejemplos comunes incluyen el uso de una consulta que crea un objeto anónimo (o colección de objetos anónimos) y pasarlo a la 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 pasar una colección de objetos a una vista que espera un solo objeto
var model = db.Foos.Where(x => x.ID == id); return View(model); // passes IEnumerable<Foo> to a view declared with @model Foo
El error se puede identificar fácilmente en tiempo de compilación declarando explícitamente el tipo de modelo en el controlador para que coincida con el modelo en la vista en lugar de usar
var
.Pasar el modelo incorrecto de una vista a una vista parcial
Dado el siguiente modelo
public class Foo { public Bar MyBar { get; set; } }
y una vista principal declarada con
@model Foo
y una vista parcial declarada con@model Bar
, luegoFoo model = db.Foos.Where(x => x.ID == id).Include(x => x.Bar).FirstOrDefault(); return View(model);
devolverá el modelo correcto a la vista principal. Sin embargo, se lanzará la excepción si la vista incluye
@Html.Partial("_Bar") // or @{ Html.RenderPartial("_Bar"); }
De forma predeterminada, el modelo que se pasa a la vista parcial es el modelo declarado en la vista principal y debe usar
@Html.Partial("_Bar", Model.MyBar) // or @{ Html.RenderPartial("_Bar", Model.MyBar); }
para pasar la instancia de
Bar
a la vista parcial. Tenga en cuenta también que si el valor deMyBar
esnull
(no se ha inicializado), de forma predeterminada seFoo
pasará al parcial, en cuyo caso, debe ser@Html.Partial("_Bar", new Bar())
Declarar un modelo en un diseño
Si un archivo de diseño incluye una declaración de modelo, todas las vistas que usan ese diseño deben declarar el mismo modelo o un modelo que se derive de ese modelo.
Si desea incluir el html para un modelo separado en un Diseño, en el Diseño, use
@Html.Action(...)
para llamar a un[ChildActionOnly]
método, inicializa ese modelo y devuelve una vista parcial para él.fuente
Model.MyBar
es nulo, puede hacer esto:@Html.Partial("_Bar", Model.MyBar, new System.Web.Mvc.ViewDataDictionary())
Fuente: https://stackoverflow.com/a/713921/4888725Esta pregunta ya tiene una gran respuesta, pero me encontré con el mismo error, en un escenario diferente: mostrar un
List
en un EditorTemplate .Tengo un modelo como este:
public class Foo { public string FooName { get; set; } public List<Bar> Bars { get; set; } } public class Bar { public string BarName { get; set; } }
Y esta es mi vista principal :
@model Foo @Html.TextBoxFor(m => m.Name, new { @class = "form-control" }) @Html.EditorFor(m => m.Bars)
Y esta es mi Bar EditorTemplate ( Bar.cshtml )
@model List<Bar> <div class="some-style"> @foreach (var item in Model) { <label>@item.BarName</label> } </div>
Y tengo este error:
El motivo de este error es que
EditorFor
ya iteraList
por usted, por lo que si le pasa una colección, se mostrará la plantilla del editor una vez para cada elemento de la colección.Así es como solucioné este problema:
Trajo los estilos fuera de la plantilla del editor y en la vista principal :
@model Foo @Html.TextBoxFor(m => m.Name, new { @class = "form-control" }) <div class="some-style"> @Html.EditorFor(m => m.Bars) </div>
Y cambió el EditorTemplate ( Bar.cshtml ) a esto:
fuente
Observe si la vista tiene el modelo requerido:
Ver
@model IEnumerable<WFAccess.Models.ViewModels.SiteViewModel> <div class="row"> <table class="table table-striped table-hover table-width-custom"> <thead> <tr> ....
Controlador
[HttpGet] public ActionResult ListItems() { SiteStore site = new SiteStore(); site.GetSites(); IEnumerable<SiteViewModel> sites = site.SitesList.Select(s => new SiteViewModel { Id = s.Id, Type = s.Type }); return PartialView("_ListItems", sites); }
En mi caso, uso una vista parcial pero se ejecuta en vistas normales
fuente