Jest kilka postów na ten temat w Stack Overflow, ale żaden z odpowiedzią, która wydaje się rozwiązać problem w mojej obecnej sytuacji.
Mam stronę z tabelą, w każdym wierszu znajduje się kilka pól tekstowych i lista rozwijana. Wszystkie listy rozwijane muszą używać tych samych danych SelectList, więc skonfigurowałem je w następujący sposób:
Kontroler
ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");
Widok
<%= Html.DropDownList("submarket_0", (SelectList)ViewData["Submarkets"], "(none)") %>
Użyłem dokładnie tej konfiguracji w wielu miejscach, ale z jakiegoś powodu w tym konkretnym widoku pojawia się błąd:
Nie ma elementu ViewData typu „IEnumerable”, który ma klucz „submarket_0”.
<%= Html.DropDownList("submarket_0", ((SelectList)ViewData["Submarkets"]).Items, "(none)") %>
DropDownList trwaIEnumerable<SelectListItem>
.<%= Html.DropDownList("submarket_0", ViewData["Submarkets"] as IEnumerable<SelectListItem>, "(none)") %>
Odpowiedzi:
Ok, więc odpowiedź została zaczerpnięta z kilku innych postów dotyczących tego problemu i jest to:
Jeśli Twój
ViewData
zawiera znakSelectList
o tej samej nazwie, co TwójDropDownList
np. „Submarket_0”, pomocnik HTML automatycznie zapełniDropDownList
te dane, jeśli nie określisz drugiego parametru, który w tym przypadku jest źródłem SelectList.To, co stało się z moim błędem, to:
Ponieważ tabela zawierająca listy rozwijane była w częściowym widoku, a tabela
ViewData
została zmieniona i nie zawieraSelectList
już odnośnika, do którego się odwołałem,HtmlHelper
(zamiast zgłaszać błąd) próbował znaleźć SelectList o nazwie „submarket_0” w ViewData (GRRRR! !!), którego NADAL nie mógł znaleźć, a następnie wyrzucił błąd :)Proszę popraw mnie jeżeli się mylę
źródło
Ajax.ActionLink
. Po prostu dodajSelectList
Get
do tego,ActionMethod
który zawiera wywołanie Ajax.Stare pytanie, ale oto inne wyjaśnienie problemu. Otrzymasz ten błąd, nawet jeśli masz mocno wpisane widoki i nie używasz ViewData do tworzenia listy rozwijanej. Przyczyna błędu może stać się jasna, gdy spojrzysz na źródło MVC :
// If we got a null selectList, try to use ViewData to get the list of items. if (selectList == null) { selectList = htmlHelper.GetSelectData(name); usedViewData = true; }
Więc jeśli masz coś takiego:
@Html.DropDownList("MyList", Model.DropDownData, "")
I
Model.DropDownData
jest null, MVC przegląda Twoje ViewData w poszukiwaniu czegoś o nazwieMyList
i zgłasza błąd, jeśli w ViewData nie ma obiektu o tej nazwie.źródło
Miałem ten sam błąd, myślę, że problem polega na tym, że tekst błędu jest mylący , ponieważ podaje fałszywą nazwę klucza.
W twoim przypadku Powinien być napisany „Nie ma elementu ViewData typu„ IEnumerable ”, który ma klucz„ Submarkets ””.
Mój błąd polegał na błędnej pisowni w kodzie widoku (w „Podrynkach”), ale tekst błędu doprowadził mnie do szału.
Piszę tę odpowiedź, ponieważ chcę powiedzieć ludziom szukającym tego błędu tak jak ja, że problem polega na tym, że nie znajduje on IENumerable, ale w var, w którym ma go szukać (w tym przypadku "Submarkets"), nie w tym, który został błędnie wyświetlony („submarket_0”) .
Zaakceptowana odpowiedź jest bardzo interesująca, ale jak powiedziałeś, konwencja jest stosowana, jeśli nie określisz drugiego parametru, w tym przypadku został on określony, ale var nie został znaleziony (w twoim przypadku, ponieważ viewdata go nie ma, w moim przypadku ponieważ Błędnie wpisałem nazwę var)
Mam nadzieję że to pomoże!
źródło
Problem polega na tym, że przesyłanie zwrotne następuje po kliknięciu przycisku przesyłania. Więc podczas publikowania danych po przesłaniu kliknij ponownie napisz przed powrotem Widok ()
ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");
źródło
Sprawdź przestrzeń nazw.
Możesz przypisać System.Web.Webpages.Html.SelectListItem w kontrolerze zamiast System.Web.Mvc.SelectListItem .
źródło
To też jest w porządku; Na przykład:
==> W pliku „NumberController”:
public ActionResult Create([Bind(Include = "NumberId,Number1,Number2,OperatorId")] Number number) { if (ModelState.IsValid) { ... ... return RedirectToAction("Index"); } ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", "OperatorSign", number.OperatorId); return View(); }
==> W pliku widoku (Create.cshtml):
<div class="form-group"> @Html.LabelFor(model => model.Number1, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Number1, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Number1, "", new { @class = "text-danger" }) </div> </div>
Teraz, jeśli usuniemy to stwierdzenie:
ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", "OperatorSign", number.OperatorId);
z tyłu następującego oświadczenia (w naszym kontrolerze):
return View();
zobaczymy ten błąd:
Nie ma elementu ViewData typu „IEnumerable”, który miałby klucz „OperatorId”.
* Więc upewnij się, że takie stwierdzenia istnieją. *
źródło
U mnie problem, który spowodował ten błąd, pojawił się, gdy zapisywałem nowy wiersz do bazy danych, ale pole było puste. W projekcie tabeli bazy danych to pole NIE ma wartości NULL. Kiedy więc próbowałem zapisać nowy wiersz z wartością null dla pola innego niż null, program Visual Studio zgłosił ten błąd. W ten sposób upewniłem się, że pole ma przypisaną wartość, a problem został rozwiązany.
źródło
W moim przypadku stwierdziłem, że omyłkowo ustawiłem metodę wpisywania jako prywatną. po zmianie prywatnego na publiczny.
[HttpPost] private async Task<ActionResult> OnPostRemoveForecasting(){}
zmień na
[HttpPost] public async Task<ActionResult> OnPostRemoveForecasting(){}
Teraz działa dobrze.
źródło
Przyczyna nie jest sprzeczna ze składnią, a nie niewłaściwym użyciem obiektów. Cykl życia obiektów w ViewData, ViewBag i View Life Cycle jest krótszy niż w sesji. Dane zdefiniowane w wzorcach zostaną utracone po odpowiedzi na żądanie (jeśli spróbujesz uzyskać dostęp po odpowiedzi na żądanie, otrzymasz wyjątki). Tak więc te pierwsze są odpowiednie do przekazywania danych między View & Controller, a drugie do przechowywania danych tymczasowych. Tymczasowe dane powinny być przechowywane w sesji, aby można było uzyskać do nich wielokrotny dostęp.
źródło
W moim przypadku wystąpił konflikt w przestrzeniach nazw, mam:
using System.Web.Mvc;
i
using System.Collections.Generic;
Wyraźnie chcę użyć Mvc, więc zadeklarowałem to jako:
new System.Web.Mvc.SelectList(...)
źródło
SelectList
wSystem.Collections.Generic
.