El modelo de elemento pasado al diccionario es de tipo...pero este diccionario requiere un modelo de elemento de tipo

c# asp.net-mvc


Esta pregunta y la respuesta wiki de la comunidad se han agregado para ayudar a cerrar numerosas preguntas sin respuesta como se discute en esta meta publicación .


Tengo un código y cuando se ejecuta,lanza una excepción diciendo:

El elemento modelo que se pasa al diccionario es del tipo Bar,pero este diccionario requiere un elemento modelo del tipo Foo

¿Qué significa esto y cómo lo arreglo?




Answer 1 Stephen Muecke


El error significa que está navegando a una vista cuyo modelo se declara como typeof Foo (usando @model Foo ), pero en realidad le pasó un modelo que es typeof Bar (tenga en cuenta que el término diccionario se usa porque se pasa un modelo a la vista a través de un ViewDataDictionary ).

El error puede ser causado por

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 una 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 que 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 , luego

Foo 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,la excepción será lanzada si la vista incluye

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

Por defecto,el modelo pasado a la vista parcial es el modelo declarado en la vista principal y es necesario utilizar

@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 de MyBar es null (no se ha inicializado), entonces, de forma predeterminada, Foo se 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,entonces todas las vistas que utilizan ese diseño deben declarar el mismo modelo,o un modelo que se deriva de ese modelo.

Si desea incluir el html para un modelo separado en un Diseño, entonces, en el Diseño, use @Html.Action(...) para llamar a un método [ChildActionOnly] que inicializa ese modelo y devuelve una vista parcial del mismo.




Answer 2 Hooman Bahreini


Esta pregunta ya tiene una gran respuesta, pero me encontré con el mismo error, en un escenario diferente: mostrar una List a 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 opinión principal :

@model Foo

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

Y este 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 elemento modelo que se pasa al diccionario es de tipo 'Bar',pero este diccionario requiere un elemento modelo de tipo 'Sistema.Colecciones.Genérico.Lista`1[Bar]


La razón de este error es que EditorFor ya itera la List a por usted, por lo que si le pasa una colección, mostrará la plantilla del editor una vez para cada elemento de la colección.

Así es como arreglé 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:

@model Bar

<label>@Model.BarName</label>



Answer 3 CelzioBR


Observe si la vista tiene el modelo requerido:

View

@model IEnumerable<WFAccess.Models.ViewModels.SiteViewModel>

<div class="row">
    <table class="table table-striped table-hover table-width-custom">
        <thead>
            <tr>
....

Controller

[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 utilizo una vista parcial pero funciona en vistas normales