Подтвердить что ты не робот

Элемент модели, переданный в словарь, имеет тип.. но для этого словаря требуется элемент модели типа

Этот вопрос и ответ сообщества wiki были добавлены, чтобы помочь закрыть многочисленные вопросы без ответа, как обсуждалось в этой мета-почте.


У меня есть код и когда он выполняется, он выдает исключение:

Элемент модели, переданный в словарь, имеет тип Bar, но для этого словаря требуется элемент модели типа Foo

Что это значит и как его исправить?

4b9b3361

Ответ 1

Ошибка означает, что вы переходите к представлению, чья модель объявлена ​​как typeof Foo (используя @model Foo), но вы фактически передали ей модель, которая является typeof Bar (обратите внимание, что термин словарь используется, потому что модель передается в представление через ViewDataDictionary).

Ошибка может быть вызвана

Передача неправильной модели из метода контроллера в представление (или частичное представление)

Общие примеры включают использование запроса, который создает анонимный объект (или коллекцию анонимных объектов) и передачи его в представление

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

или передачи коллекции объектов в представление, которые ожидают один объект

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

Ошибка можно легко идентифицировать во время компиляции, явно объявив тип модели в контроллере, чтобы она соответствовала модели в представлении, а не используя var.

Передача неправильной модели из представления в частичный вид

Учитывая следующую модель

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

и основной вид, объявленный с помощью @model Foo, и частичное представление, объявленное с помощью @model Bar, затем

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

вернет правильную модель к основному виду. Однако исключение будет выбрано, если представление включает

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

По умолчанию модель, переданная частичному представлению, представляет собой модель, объявленную в основном представлении, и вам нужно использовать

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

передать экземпляр Bar в частичный вид. Заметим также, что если значение MyBar равно null (не было инициализировано), то по умолчанию Foo будет передано частичному, и в этом случае он должен быть

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

Объявление модели в макете

Если файл макета включает объявление модели, то все представления, которые используют этот макет, должны объявлять одну и ту же модель или модель, полученную из этой модели.

Если вы хотите включить html для отдельной модели в макет, то в макете используйте @Html.Action(...) для вызова метода [ChildActionOnly], который инициализирует эту модель и возвращает частичное представление для нее.

Ответ 2

Наблюдайте, имеет ли вид требуемую модель:

Просмотр

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

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

контроллер

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

В моем случае я использую частичный вид, но работаю с нормальными представлениями