Es gibt kein ViewData-Element vom Typ 'IEnumerable <SelectListItem>' mit dem Schlüssel 'xxx'.


86

Es gibt ein paar Beiträge zu Stack Overflow, aber keine mit einer Antwort, die das Problem in meiner aktuellen Situation zu beheben scheint.

Ich habe eine Seite mit einer Tabelle, jede Zeile hat eine Reihe von Textfeldern und ein Dropdown. Alle Dropdowns müssen dieselben SelectList-Daten verwenden, daher habe ich sie wie folgt eingerichtet:

Regler

ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");

Aussicht

<%= Html.DropDownList("submarket_0", (SelectList)ViewData["Submarkets"], "(none)") %>

Ich habe genau dieses Setup an vielen Stellen verwendet, aber aus irgendeinem Grund erhalte ich in dieser speziellen Ansicht den Fehler:

Es gibt kein ViewData-Element vom Typ 'IEnumerable' mit dem Schlüssel 'submarket_0'.


1
Hast du das versucht? <%= Html.DropDownList("submarket_0", ((SelectList)ViewData["Submarkets"]).Items, "(none)") %>DropDownList dauert IEnumerable<SelectListItem>.
LukLed

@LukLed - so habe ich schließlich die Fehlerquelle gefunden :) sowie Informationen aus einigen anderen Posts! Danke
Jimbo

<%= Html.DropDownList("submarket_0", ViewData["Submarkets"] as IEnumerable<SelectListItem>, "(none)") %>
Arvis

Ich bin heute darauf gestoßen und habe festgestellt, dass das zweite Argument in meinem DropDownList-Helfer laut dem folgenden Ergebnis von @jonathansewell null war.
Ken Palmer

Antworten:


78

Ok, die Antwort wurde von einigen anderen Posts zu diesem Problem abgeleitet und lautet:

Wenn Ihr ViewDataa SelectListden gleichen Namen wie Ihr DropDownList"submarket_0" enthält, füllt der HTML-Helfer Ihr automatisch DropDownListmit diesen Daten, wenn Sie nicht den zweiten Parameter angeben, der in diesem Fall die Quell-SelectList ist.

Was mit meinem Fehler passiert ist, war:

Da sich die Tabelle mit den Dropdown-Listen in einer Teilansicht befand und die ViewDatageändert wurde und nicht mehr die von SelectListmir referenzierte enthielt, versuchte die HtmlHelper(anstatt einen Fehler auszulösen), die SelectList mit dem Namen "submarket_0" in den ViewData (GRRRR! !!) was es NOCH nicht finden konnte und dann einen Fehler drauf warf :)

Bitte korrigiere mich wenn ich falsch liege


104
Ich habe diesen Fehler erhalten, weil meine Sammlung von SelectListItems für die Dropdown-Liste null war. Dies ist das gleiche Problem, das Sie meiner Meinung nach hatten.
Jonathan Sewell

6
Wenn Sie mit diesem Problem konfrontiert sind, schließen Sie Ihre Dropdown-Liste vorübergehend in eine Nullprüfung ein, z. B. @if (ViewData ["Submarkets"]! = Null). Wenn die Ansicht dann ohne Fehler (und ohne Ihre Dropdown-Liste) gerendert wird, haben Sie Ihr Problem identifiziert. Der Fehler "Datenelement ohne Ansicht" ist in diesem Fall sehr irreführend.
GDB

Ich bin mit einem darauf gestoßen Ajax.ActionLink. Fügen Sie einfach die SelectList Getzu der ActionMethod, die die Ajax - Aufruf enthält.
stinken

Ja! Ich hatte den Namen der Liste geändert, die ich vom Controller an ViewData übergeben hatte, und ihn in der Ansicht nicht geändert. Das ist eine wirklich schrecklich verwirrende Fehlermeldung!
Neminem

1
@ JonathanSewell danke, danke, danke! Das war mein genaues Problem.
Johnw182

29

Alte Frage, aber hier ist eine andere Erklärung des Problems. Diese Fehlermeldung wird auch dann angezeigt, wenn Sie stark typisierte Ansichten haben und ViewData nicht zum Erstellen Ihrer Dropdown-Liste verwenden. Der Grund für den Fehler kann deutlich werden, wenn Sie sich die MVC-Quelle ansehen :

// 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;
}

Also, wenn Sie etwas haben wie:

@Html.DropDownList("MyList", Model.DropDownData, "")

Und Model.DropDownDataist null, MVC durchsucht Ihre ViewData nach etwas mit dem Namen MyListund gibt einen Fehler aus, wenn in ViewData kein Objekt mit diesem Namen vorhanden ist.


1
Hallo, das ist auch mein Problem. Was machen wir, wenn die Liste null ist ? können Sie etwas vorschlagen,
Transformator

4
@transformer Am einfachsten wäre es, Model.DropDownData auf eine leere Liste anstatt auf null zu setzen. Wenn dies nicht möglich ist, können Sie Ihr Rasiermesser-Markup ändern, um zu überprüfen, ob die Liste null ist, und in diesem Fall eine leere Auswahlliste rendern.
Hawkke

15

Ich hatte den gleichen Fehler, ich denke, das Problem ist, dass der Fehlertext verwirrend ist , weil er einen falschen Schlüsselnamen enthält.

In Ihrem Fall sollte "Es gibt kein ViewData-Element vom Typ 'IEnumerable' mit dem Schlüssel" Teilmärkte "" angezeigt werden.

Mein Fehler war eine Rechtschreibfehler im Ansichtscode (Ihre "Teilmärkte"), aber der Fehlertext hat mich verrückt gemacht.

Ich poste diese Antwort, weil ich sagen möchte, dass Leute, die wie ich nach diesem Fehler suchen, das Problem darin besteht, dass sie nicht die IENumerable finden, sondern in der Variablen, nach der sie suchen sollen (in diesem Fall "Teilmärkte"). nicht in dem fehlerhaft angezeigten ("submarket_0") .

Die akzeptierte Antwort ist sehr interessant, aber wie Sie sagten, wird die Konvention angewendet, wenn Sie den 2. Parameter nicht angeben. In diesem Fall wurde er angegeben, aber die Variable wurde nicht gefunden (in Ihrem Fall, weil die Ansichtsdaten ihn nicht hatten, in meinem Fall, weil Ich habe den Variablennamen falsch geschrieben.

Hoffe das hilft!


9

Das Problem ist, dass das Zurücksenden beim Klicken auf die Schaltfläche "Senden" erfolgt. Klicken Sie also beim Posten von Daten beim Senden erneut auf Schreiben, bevor Sie View () zurückgeben.

ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");

3

Überprüfen Sie den Namespace.

Sie können System.Web.Webpages.Html.SelectListItem im Controller anstelle von System.Web.Mvc.SelectListItem zuweisen .


1

Das ist auch in Ordnung; Zum Beispiel:
==> In der Datei "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();
}

==> In der Ansichtsdatei (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>

Wenn wir nun diese Aussage entfernen:

ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", "OperatorSign", number.OperatorId);

von der Rückseite der folgenden Anweisung (in unserem Controller):

return View();

Wir werden diesen Fehler sehen:

Es gibt kein ViewData-Element vom Typ 'IEnumerable' mit dem Schlüssel 'OperatorId'.

* Stellen Sie also sicher, dass diese Aussagen vorhanden sind. * *


0

Für mich trat das Problem, das diesen Fehler verursachte, auf, als ich eine neue Zeile in der Datenbank speicherte, aber ein Feld war null. Im Entwurf der Datenbanktabelle ist dieses Feld NICHT NULL. Als ich versuchte, eine neue Zeile mit einem Nullwert für ein Nicht-Null-Feld zu speichern, warf Visual Studio diesen Fehler aus. Daher habe ich sichergestellt, dass dem Feld ein Wert zugewiesen wurde und das Problem behoben wurde.


0

In meinem Fall habe ich festgestellt, dass ich die Post-Methode fälschlicherweise als privat festgelegt habe. nach dem Wechsel von privat zu öffentlich.

[HttpPost]
private async Task<ActionResult> OnPostRemoveForecasting(){}

ändern

[HttpPost]
public async Task<ActionResult> OnPostRemoveForecasting(){}

Funktioniert jetzt gut.


0

Die Ursache widerspricht nicht der Syntax, sondern der unangemessenen Verwendung von Objekten. Der Lebenszyklus von Objekten in ViewData, ViewBag und View Life Cycle ist kürzer als in der Sitzung. In den Formern definierte Daten gehen nach einer Anforderungsantwort verloren (wenn Sie versuchen, nach einer Anforderungsantwort darauf zuzugreifen, erhalten Sie Ausnahmen). Die Formers eignen sich daher zum Übertragen von Daten zwischen View & Controller, während letztere zum Speichern temporärer Daten geeignet sind. Die temporären Daten sollten in der Sitzung gespeichert werden, damit mehrmals darauf zugegriffen werden kann.


-1

In meinem Fall gab es einen Konflikt in den Namespaces, ich habe:

using System.Web.Mvc;

und

using System.Collections.Generic;

Ich möchte ausdrücklich den Mvc verwenden, also habe ich ihn wie folgt deklariert:

new System.Web.Mvc.SelectList(...)

1
Wenn meine Augen mich nicht täuschen, gibt es kein SelectListIn System.Collections.Generic.
Erik Philips
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.