Alle, bitte klären Sie meine Verwirrung auf, wie die Modellbindung mit IEnumerables und Editorvorlagen funktioniert.
Ich habe eine Ansicht, Approve.cshtml
@model IEnumerable<MvcWebsite.Models.Approve>
<table>
<tr>
<th>
Name
</th>
</tr>
@Html.EditorForModel()
</table>
Ein Modell, Approve.cs
public class Approve
{
public string Name { get;set;}
public string Role { get; set; }
}
Und eine Editorvorlage
@model MvcWebsite.Models.Approve
@using (Html.BeginForm("Approve", "Registration", FormMethod.Post))
{
<tr>
<td>
@Html.HiddenFor(m => m.Name)
@Html.EditorFor(m => m.Role)
</td>
<td>
<input type="submit" value="Approve" class="submit-button" />
</td>
</tr>
}
Das ist alles schön und gut. Es gibt die folgende Ausgabe aus.
<input name="[0].Name" type="hidden" value="" />
....
Jedoch in meinem Controller, kann ich nicht scheinen, um Werte zurück für das Modell (Bindung) zu erhalten.
[HttpPost]
public ActionResult Approve(Approve approveModel)
{
.... approveModel has all default values
}
Kann mir jemand erklären, was ich hier falsch mache? Ich habe den Code abgekürzt, ich verwende die Editor-Vorlage mit anderen EditorFor und HiddenFor Feldern aus meinem Modell...
Bearbeitet: Ich habe im Grunde ein Tabellenlayout, jeweils mit dem Namen des Benutzers, ein Textfeld, wo ich ihre Rolle (Benutzer oder Admin) und dann eine Schaltfläche Genehmigen eingeben kann, die an meinen Controller sendet. Aus diesem Grund möchte ich nur ein einziges Approve-Objekt zurückgeben. Ich kann die gesamte IEnumerable an meinen Controller zurückgeben, aber wenn ich das tue, wie kann ich sagen, welche der Elemente war die, die ich die Schaltfläche Genehmigen (senden) für geklickt?
EDIT: Ich habe den Code so geändert, dass ich ein einziges Formular habe, das meine gesamte Ansicht Approve.cshtml umgibt
@model IEnumerable<MvcWebsite.Models.Approve>
@using (Html.BeginForm("Approve", "Program", FormMethod.Post))
{
<table>
<tr>
<th>
Name
</th>
</tr>
@Html.EditorForModel()
</table>
}
Und änderte dann den Controller in
[HttpPost]
public ActionResult Approve(IEnumerable<Approve> approvals)
{
// ???????????????????????
}
Jetzt weiß ich immer noch nicht, woher ich weiß, für welche Zeile ich auf "Genehmigen" geklickt habe. Ich weiß, dass es andere Möglichkeiten gibt, diese Aufgabe zu erfüllen (erstellen Sie ein Kontrollkästchen für genehmigen, und genehmigen Sie alles markiert, usw.) Jedoch brauche ich die Fähigkeit, eine Schaltfläche klicken und nur 1 Zeile zurück in die Datenbank zu speichern, unabhängig davon, ob der Benutzer Informationen in die anderen Zeilen eingegeben. Ist es bessere Praxis, meine IEnumerable innerhalb der eigenen Modell (d.h. AllApprovals) zu wickeln und dann Hilfseigenschaften zu diesem übergeordneten Modell (SelectedIndex, etc.) hinzufügen? Wenn dies der richtige Ansatz ist, wie setze ich dann den SelectedIndex nach dem Klicken auf eine Genehmigungsschaltfläche? Ist das noch Jquery Magie oder gibt es eine korrekte MVC Weg, dies zu erreichen? Jquery Magie scheint sehr hackish zu mir?
EDIT: Basierend auf Brians Antwort, hier ist meine endgültige Version. Es fühlt sich immer noch nicht ganz richtig an, aber es funktioniert!
Siehe
@model IEnumerable<MvcWebsite.Models.Approve>
<table>
<tr>
<th>
Name
</th>
</tr>
@Html.EditorForModel()
</table>
Editor-Vorlage
@using (Html.BeginForm("Approve", "Registration", FormMethod.Post))
{
<tr>
<td>
@Html.HiddenFor(m => m.Name)
@Html.EditorFor(m => m.Role)
</td>
<td>
<input type="submit" value="Approve" class="submit-button" />
</td>
</tr>
}
Controller
[HttpPost]
public ActionResult Approve([Bind(Prefix="approval")]Approve approval) {
// WORKS!
}