Das an das Wörterbuch übergebene Modellelement ist vom Typ. Für dieses Wörterbuch ist jedoch ein Modellelement vom Typ erforderlich

84

Diese Frage und die Antwort des Community-Wikis wurden hinzugefügt, um das Schließen zahlreicher unbeantworteter Fragen zu erleichtern, die in diesem Meta-Beitrag behandelt werden .


Ich habe Code und wenn er ausgeführt wird, wird eine Ausnahme ausgelöst, die besagt:

Das an das Wörterbuch übergebene Modellelement ist vom Typ Bar, für dieses Wörterbuch ist jedoch ein Modellelement vom Typ Foo erforderlich

Was bedeutet das und wie behebe ich es?

Gemeinschaft
quelle
1
Ich habe diesen Fehler bei der Verwendung von return Viewstatt bekommen return PartialView, also ist das etwas zu überprüfen
Richard Housham

Antworten:

91

Der Fehler bedeutet, dass Sie zu einer Ansicht navigieren, deren Modell als typeof deklariert ist Foo(mithilfe von @model Foo), aber tatsächlich ein Modell übergeben haben, das typeof ist Bar(beachten Sie, dass der Begriff Wörterbuch verwendet wird, weil ein Modell über a an die Ansicht übergeben wird ViewDataDictionary). .

Der Fehler kann verursacht werden durch

Übergeben des falschen Modells von einer Controller-Methode an eine Ansicht (oder Teilansicht)

Häufige Beispiele sind die Verwendung einer Abfrage, mit der ein anonymes Objekt (oder eine Sammlung anonymer Objekte) erstellt und an die Ansicht übergeben wird

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

oder Übergeben einer Sammlung von Objekten an eine Ansicht, die ein einzelnes Objekt erwartet

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

Der Fehler kann zur Kompilierungszeit leicht identifiziert werden, indem der Modelltyp in der Steuerung explizit deklariert wird, damit er mit dem Modell in der Ansicht übereinstimmt, anstatt ihn zu verwenden var.

Übergabe des falschen Modells von einer Ansicht an eine Teilansicht

Gegeben das folgende Modell

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

und dann eine Hauptansicht, die mit deklariert wurde, @model Foound eine Teilansicht, die mit deklariert @model Barwurde

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

kehrt das richtige Modell zur Hauptansicht zurück. Die Ausnahme wird jedoch ausgelöst, wenn die Ansicht enthält

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

Standardmäßig ist das an die Teilansicht übergebene Modell das in der Hauptansicht deklarierte Modell, das Sie verwenden müssen

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

um die Instanz von Baran die Teilansicht zu übergeben. Beachten Sie auch, dass, wenn der Wert von MyBaris ist null(nicht initialisiert wurde), standardmäßig Fooan den Teil übergeben wird. In diesem Fall muss dies der Fall sein

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

Deklarieren eines Modells in einem Layout

Wenn eine Layoutdatei eine Modelldeklaration enthält, müssen alle Ansichten, die dieses Layout verwenden, dasselbe Modell oder ein Modell deklarieren, das von diesem Modell abgeleitet ist.

Wenn Sie den HTML-Code für ein separates Modell in ein Layout aufnehmen möchten, initialisieren Sie im Layout mit, um @Html.Action(...)eine [ChildActionOnly]Methode aufzurufen , die dieses Modell initialisiert und eine Teilansicht dafür zurückgibt.

Stephen Muecke
quelle
26
+1 für "Beachten Sie auch, dass wenn der Wert von MyBar null ist (nicht initialisiert wurde), Foo standardmäßig an den Teil übergeben wird. In diesem Fall muss es sein". Sehr wichtiger Hinweis.
Smix
Ich erhalte den gleichen Fehler, wenn eine Teilansicht in einem Layout ohne definierten Modelltyp vorhanden ist. Die Teilansicht stürzt ab, weil sie das Modell von der Indexseite empfängt, wenn keine definiert oder benötigt wird. Wenn ich das Teilmodell auf IndexModel setze, ist die ViewData-Eigenschaft null! ?? Wie kann ich dieses Szenario beheben? Das Verschieben des Teils in das Layout funktioniert, aber ich möchte verstehen, wie es funktioniert.
Etienne Charland
Ich bin auf den gleichen Fehler gestoßen, als meine Teilansicht oben "@page" ohne "@model" hatte. Das Entfernen von "@page" löste das Problem.
EKanadily
1
Wenn Sie absichtlich ein Nullmodell an die Teilansicht senden möchten, wenn Model.MyBarNull ist, können Sie dies tun: @Html.Partial("_Bar", Model.MyBar, new System.Web.Mvc.ViewDataDictionary()) Quelle: https://stackoverflow.com/a/713921/4888725
Kirk Grover
6

Diese Frage hat bereits eine gute Antwort, aber ich bin in einem anderen Szenario auf denselben Fehler gestoßen : Anzeigen Listin einer EditorTemplate .

Ich habe ein Modell wie dieses:

public class Foo
{
    public string FooName { get; set; }
    public List<Bar> Bars { get; set; }
}

public class Bar
{
    public string BarName { get; set; }
}

Und das ist meine Hauptansicht :

@model Foo

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

Und das ist meine Bar EditorTemplate ( Bar.cshtml )

@model List<Bar>

<div class="some-style">
    @foreach (var item in Model)
    {
        <label>@item.BarName</label>
    }
</div>

Und ich habe diesen Fehler bekommen:

Das an das Wörterbuch übergebene Modellelement ist vom Typ 'Bar', für dieses Wörterbuch ist jedoch ein Modellelement vom Typ 'System.Collections.Generic.List`1 [Bar] erforderlich.


Der Grund für diesen Fehler ist, dass das EditorForbereits Listfür Sie iteriert wird. Wenn Sie also eine Sammlung an diese übergeben, wird die Editorvorlage für jedes Element in der Sammlung einmal angezeigt.

So habe ich dieses Problem behoben:

Brachte die Stile außerhalb der Editorvorlage in die Hauptansicht :

@model Foo

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

Und änderte die EditorTemplate ( Bar.cshtml ) in diese:

@model Bar

<label>@Model.BarName</label>
Hooman Bahreini
quelle
1
Super, du hast mich gerade gerettet, nachdem ich mir eine halbe Stunde am Kopf gekratzt hatte. Funktioniert auch für ASP.NET Core 3.1 MVC.
Uwe Keim
5

Beobachten Sie, ob die Ansicht das erforderliche Modell hat:

Aussicht

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

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

Regler

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

In meinem Fall verwende ich eine Teilansicht, läuft aber in normalen Ansichten

CelzioBR
quelle
1
Was hat das mit der Frage zu tun?
2
@ StephenMuecke this champs - Das in das Wörterbuch übergebene Modellelement ist vom Typ Bar, für dieses Wörterbuch ist jedoch ein Modellelement vom Typ Foo
CelzioBR vom