To pytanie i odpowiedź wiki społeczności zostały dodane, aby pomóc w zamknięciu wielu pytań bez odpowiedzi, omówionych w tym meta poście .
Mam jakiś kod i kiedy się wykonuje, rzuca wyjątek mówiący:
Element modelu przekazany do słownika jest typu Bar, ale ten słownik wymaga elementu modelu typu Foo
Co to oznacza i jak to naprawić?
c#
asp.net-mvc
Społeczność
źródło
źródło
return View
zamiast,return PartialView
więc to jest coś do sprawdzeniaOdpowiedzi:
Błąd oznacza, że nawigujesz do widoku, którego model jest zadeklarowany jako typeof
Foo
(przy użyciu@model Foo
), ale w rzeczywistości przekazałeś mu model, który jest typeofBar
(zwróć uwagę, że używany jest termin słownik, ponieważ model jest przekazywany do widoku za pośrednictwem aViewDataDictionary
) .Błąd może być spowodowany przez
Przekazywanie niewłaściwego modelu z metody kontrolera do widoku (lub częściowego widoku)
Typowe przykłady obejmują użycie zapytania, które tworzy anonimowy obiekt (lub kolekcję obiektów anonimowych) i przekazanie go do widoku
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
lub przekazanie kolekcji obiektów do widoku, który oczekuje pojedynczego obiektu
var model = db.Foos.Where(x => x.ID == id); return View(model); // passes IEnumerable<Foo> to a view declared with @model Foo
Błąd można łatwo zidentyfikować w czasie kompilacji, jawnie deklarując typ modelu w kontrolerze, aby pasował do modelu w widoku, zamiast używać
var
.Przekazywanie niewłaściwego modelu z widoku do częściowego widoku
Biorąc pod uwagę następujący model
public class Foo { public Bar MyBar { get; set; } }
a głównym widoku zadeklarowana
@model Foo
i częściowym widokiem zadeklarowana@model Bar
, a następnieFoo model = db.Foos.Where(x => x.ID == id).Include(x => x.Bar).FirstOrDefault(); return View(model);
zwróci prawidłowy model do widoku głównego. Jednak wyjątek zostanie zgłoszony, jeśli widok zawiera
@Html.Partial("_Bar") // or @{ Html.RenderPartial("_Bar"); }
Domyślnie model przekazany do widoku częściowego jest modelem zadeklarowanym w widoku głównym i należy go użyć
@Html.Partial("_Bar", Model.MyBar) // or @{ Html.RenderPartial("_Bar", Model.MyBar); }
przekazać instancję
Bar
do częściowego widoku. Zauważ również, że jeśli wartośćMyBar
isnull
(nie została zainicjowana), to domyślnieFoo
zostanie przekazana do częściowej, w takim przypadku musi być@Html.Partial("_Bar", new Bar())
Deklarowanie modelu w układzie
Jeśli plik układu zawiera deklarację modelu, wszystkie widoki korzystające z tego układu muszą deklarować ten sam model lub model pochodzący z tego modelu.
Jeśli chcesz dołączyć
@Html.Action(...)
kod HTML dla oddzielnego modelu do układu, to w układzie użyj, aby wywołać[ChildActionOnly]
metodę inicjuje ten model i zwraca dla niego częściowy widok.źródło
Model.MyBar
jest zerowy, możesz to zrobić:@Html.Partial("_Bar", Model.MyBar, new System.Web.Mvc.ViewDataDictionary())
Źródło: https://stackoverflow.com/a/713921/4888725To pytanie ma już świetną odpowiedź, ale napotkałem ten sam błąd, w innym scenariuszu: wyświetlając
List
w EditorTemplate .Mam taki model:
public class Foo { public string FooName { get; set; } public List<Bar> Bars { get; set; } } public class Bar { public string BarName { get; set; } }
I to jest mój główny pogląd :
@model Foo @Html.TextBoxFor(m => m.Name, new { @class = "form-control" }) @Html.EditorFor(m => m.Bars)
A to jest mój szablon Bar EditorTemplate ( Bar.cshtml )
@model List<Bar> <div class="some-style"> @foreach (var item in Model) { <label>@item.BarName</label> } </div>
I dostałem ten błąd:
Przyczyną tego błędu jest to, że
EditorFor
już wykonuje iteracjęList
dla Ciebie, więc jeśli przekażesz do niej kolekcję, wyświetli szablon edytora raz dla każdego elementu w kolekcji.Oto jak naprawiłem ten problem:
Przeniesiono style poza szablon edytora i do głównego widoku :
@model Foo @Html.TextBoxFor(m => m.Name, new { @class = "form-control" }) <div class="some-style"> @Html.EditorFor(m => m.Bars) </div>
I zmieniłem EditorTemplate ( Bar.cshtml ) na to:
źródło
Obserwuj, czy widok ma wymagany model:
Widok
@model IEnumerable<WFAccess.Models.ViewModels.SiteViewModel> <div class="row"> <table class="table table-striped table-hover table-width-custom"> <thead> <tr> ....
Kontroler
[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); }
W moim przypadku używam częściowego widoku, ale działa w normalnych widokach
źródło