asp.net Veröffentlichen Sie ein Formular mit der Aktionsmethode „View Model to Controller“.
-
21-12-2019 - |
Frage
Ich habe ein ziemlich komplexes Formular, das ich an meinen MVC-Controller senden muss.
Hier ist das Ansichtsmodell, das ich bei der Erstellung zunächst an die Ansicht übergebe:
public class EditViewModel
{
public Service service { get; set; }
public bool sms { get; set; }
public bool email { get; set; }
public string userId { get; set; }
}
Hier ist meine Ansicht (vereinfacht):
@model IList<Service_Monitor_Web_Interface.Models.ViewModels.EditViewModel>
@{
ViewBag.Title = "Configure User Notifications";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm("Edit", "Users", FormMethod.Post, new { @class = "stdform stdform2", role = "form" }))
{
@Html.AntiForgeryToken()
<hr />
<p>
<label><u> Service:</u> </label>
<span class="field">
<u>Notification Methods:</u>
</span>
</p>
for (int i = 0; i < Model.Count; i++)
{
<p>
<label>@Model[i].service.Name</label>
<span class="field">
@Html.CheckBoxFor(model => model[i].sms)
SMS
@Html.CheckBoxFor(model => model[i].email)
Email
</span>
</p>
}
<br clear="all" /><br />
<p class="stdformbutton">
<button class="submit radius2">Save</button>
<input type="reset" class="reset radius2" value="Reset Form" />
</p>
}
Und hier ist meine Action-Methode in meinem Controller:
//
// POST: /Users/Edit
[HttpPost]
public ActionResult Edit(IList<EditViewModel> viewModel)
{
return View(viewModel);
}
Wie kann ich mein Ansichtsmodell binden, wenn ich es auf dem Controller erhalte?Derzeit empfängt die Aktionsmethode beim Debuggen ein ViewModel, das so aussieht:
Wie kann ich dafür sorgen, dass Service und Benutzer-ID nicht null sind?
Lösung
Beachten Sie, dass in den Lambdas Ihrer Helfer „in“ heißt model => service.sms
rechter Teil (service.sms
) ist formal nicht vom linken Teil abgeleitet (model
).Das verursacht alles name
sorgt dafür, dass die Attribute der resultierenden Eingaben gleich sind, und gibt Ihnen Anforderungsparameter, die Sie nicht erwartet haben.
Die gängige Praxis ist die Verwendung for
statt foreach
in Schleifenkoffern.Auf diese Weise werden Namensattribute für das resultierende HTML korrekt generiert:
for(int i=0; i<Model.Count; i++)
{
<p>
<label>@Model[i].service.Name</label>
<span class="field">
@Html.CheckBoxFor(model => model[i].sms)
SMS
@Html.CheckBoxFor(model => model[i].email)
Email
</span>
</p>
}
Beachten Sie, dass dies erforderlich ist Model
vom Typ implementierend sein IList
statt IEnumerable
.
Aktualisieren. Für andere Werte, für die es keine Benutzeroberfläche gibt, können Sie versteckte Felder verwenden, sodass sie für den Benutzer nicht sichtbar sind und dennoch auf dem Server gepostet werden:
<label>@Model[i].service.Name</label>
<span class="field">
@Html.CheckBoxFor(model => model[i].sms)
SMS
@Html.CheckBoxFor(model => model[i].email)
Email
@Html.HiddenFor(mode => model[i].userId)
@Html.HiddenFor(mode => model[i].service.Name)
...other field of service you want to be posted...
</span>