Hallo zusammen,
ich versuche gerade, den Wert einer Checkbox in meinem Controller abzufragen, und es kommt immer "False" als Ergebnis.
public class MySubmitModel: SubmitModelBase
{
..
public bool Asdf { get; set; }
}
In der View
@Html.CheckBoxFor(m => m.SubmitModel.Asdf)
...
<input type="submit" value="Save" />
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, MySubmitModel mySubmitModel)
{
....
if(mySubmitModel.Asdf) // Immer False
{
...
}
}
(Anmerkung: Den HTML-Helper verwende ich nur aus Verzweiflung, weil ichs erstmal zum Laufen bekommen möchte 😉. Andere Properties (strings) funktionieren prima über das SubmitModel)
Die Checkbox ist immer false. Muss ich noch irgendwas beachten? Habe ich was vergessen?
Habe schon das Standard-Beispiel von MS rausgekramt und dort geschaut. MMn machen die alles genau gleich.
Grüsse
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Hi,
du musst deinen Parameter "submitmodel" nennen und nicht "mySubmitModel", damit es vom ModelBinder gefüllt wird. Eigentlich müssten ja alle Werte in deinem Model nicht übernommen worden sein. Prüf das mal.
Hallo Sarc,
danke für die Antwort.
Das SubmitModel heisst schon "SubmitModel". Ich hab es nur hier im Forum "MySubmitModel" genannt.
Alle andren Werte werden korrekt abgefüllt. Sind allerdings strings. Nur der boolsche Wert der Checkbox ist immer false. Genau das macht mich ja stutzig.
Gruss
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Und was für einen Wert erhältst du, wenn du den Request parameter direkt abfrägst (Request.Params["SubmitModel.Asdf"]
)
Ich hab das hier mal nachgestellt und habe keine Probleme damit.
Hallo Sarc,
der generierte HTML-Code schaut so aus
<input data-val="true" data-val-required="Das Feld "Asdf" ist erforderlich." id="SubmitModel_Asdf" name="SubmitModel.Asdf" type="checkbox" value="true" /><input name="SubmitModel.Asdf" type="hidden" value="false" />
und wenn ich den Wert direkt prüfe
string s = Request.Params["SubmitModel.Asdf"];
steht in "s" = "true,false".
Jetzt blick ichs gar nicht mehr.
Gruss
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Hi,
also über den MVC CheckBox HtmlHelper wird immer ein Hidden field mitgeneriert. Wenn die Checkbox nämlich nicht gecheckt ist, wird sie auch nicht als Parameter übertragen, daher das Hidden field (siehe auch asp.net mvc: why is Html.CheckBox generating an additional hidden input)
Das Request.Params["SubmitModel.Asdf"]
sieht bei mir genauso aus und es wird auch in das Model übernommen. Sicher dass du nicht noch was anderes machst?
Edit: Mein Minimal Setup sieht so aus:
public class HomeController : Controller
{
public ActionResult Blub()
{
var model = new ViewModel();
model.SubmitModel = new MySubmitModel();
return View(model);
}
[HttpPost]
public ActionResult Blub(MySubmitModel submitmodel)
{
return View();
}
}
public class ViewModel
{
public MySubmitModel SubmitModel { get; set; }
}
public class MySubmitModel
{
public bool SomeValue { get; set; }
public string SomeText { get; set; }
}
// die view
@model MvcApplication2.Controllers.ViewModel
@{
ViewBag.Title = "Title";
}
@using (Html.BeginForm())
{
@Html.TextBoxFor(f => f.SubmitModel.SomeText)
@Html.CheckBoxFor(f => f.SubmitModel.SomeValue)
<input type="submit" value="Save" />
}
Hallo Sarc,
habs grad nochmal überprüft.
Es werden alle anderen Values übernommen. Nur die Checkbox nicht. Ich habe noch das "AntiForgeryToken" in der Form. Aber Grundsätzlich ist es dasselbe. Lustigerweise geht ja auch das MS Beispiel. Das ist ja nicht viel anders.
Ich hab keine Ahnung mehr.
Ich fülle mein SubmitModel vorher noch mit Standardwerten. Und gebe es dann an die View. Das Submitmodel heisst als Parameter in der HttpPost-Funktion übrigens nicht "submitModel" sondern hat einen andren Namen. Nur das Property auf dem ViewModel heisst "SubmitModel". Spielt das eine Rolle?
Ändere ich den Namen der HttpPost-Funktion im Controller auf "SubmitModel" sind alle Werte "null".
Ich probier nochmal an der Namensgebung rum.
Mehr fällt mir im Moment nicht mehr ein.
Gruss
Coffeebean
=====
Edit: Wenn ich das SubmitModel als parameter "submitModel" nenne, geht zwar die Checkbox, aber kein anderer Wert funktioniert. Erklären kann ichs mir nicht.
EDIT 2: man sollte sagen, dass ich keine HTML-Helper verwende.
Parameter "submitModel" mit
<textarea id="SubmitModel_Comment" name="SubmitModel.Comment" ...>@(Model.SubmitModel.Comment)</textarea>
(wird vom HTML-Helper generiert)
funktioniert.
Parameter "submitModel" mit
<textarea id="Comment" name="Comment" ...>@(Model.SubmitModel.Comment)</textarea>
funktioniert nicht.
Parameter "mySubmitModel" mit
<textarea id="Comment" name="Comment" ...>@(Model.SubmitModel.Comment)</textarea>
funktioniert auch, ABER keine Checkboxen! Das hab ich bis hierher rausgefunden 😉
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Hallo,
also mein oben genannter Beispiel Code zeigt ja, dass es funktioniert, sowohl mit einem normalen string als auch mit der Checkbox.
Ausgehend davon, solltest du deinen Code Stück für Stück erweitern und prüfen, wann und wo sich ein Problem einstellt.
Mehr kann ich dazu momentan auch nicht sagen.
Hi,
benutze mal
@Html.EditorFor(m => m.SubmitModel.Asdf)
statt ...CheckboxFor und schreib, ob das hilft.
Dann würde mich eines interessieren, vielleicht gibt's einen Grund dafür...
Warum der Typ "ViewModel"?
Du könntest doch an Deine View direkt das SubmitModel übergeben.
[...]
SubmitModel m = new SubmitModel();
return View(m);
Und dann in der View
@Html.EditorFor(m => m.Asdf)
Oder hast Du mehrere Formulare in der View?
--
mfG.
Marcel Eckhoff
Hallo zusammen,
danke für die Antworten.
Ich habe in meiner View mehrere Sachen ausser der Form. Daher baue ich die View u.a. mit dem Submitmodel auf, aber sie hat noch mehrere andere Sachen drauf.
Grundsätzlich weiss ich ja, wie es funktioniert. Da ich HTML-Helper weglassen möchte nehme ich im Prinzip den von einem HTML-Helper produzierten Code und gebe ihn ein, dann funktioniert auch alles, wenn der Parameter in der HttpPost-Funktion" submitModel" heisst.
Ich frage mich nur, warum es auch anders funktioniert. Jedoch eben nur so halb, weil ja Checkboxes nicht gehen.
Ich les mich da nochmal ein. Muss ja irgendwie erklärbar sein 😉
Vielen Dank für eure Antworten.
Gruss
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Bool ist ein heikler Typ bei solchen Submits.
Wieso?
Ein True wirst Du im Post aller Browser finden. Ein False unterdrücken einige Browser "um Traffic zu sparen".
Daher kann es zB beim Nullable<Bool> sein, dass ein Null rauskommt, obwohl eigentlich ein False gemeint war.
Kann man wunderbar im Firebug nachvollziehen.
Dass Du die View mit dem ViewModel aufbaust und die abgesendete Form mit SubmitModel empfängst hast Du sicher von meinen Beispielen hier entnommen und ist auch richtig.
Sarc verwendet's ebenfalls in einen Beispielen hier korrekt.
Mein Beispiel dazu:
public enum MVCCheckboxResult
{
NO,
YES
}
public class MySubmitModel
{
public MVCCheckboxResult SomeValue { get; set; }
public string SomeText { get; set; }
}
Damit fange ich NO bzw "null" und YES einwandfrei ab. Wichtig: negatives zuerst!
Ganz wichtig: SubmitModel ist nur ein Helfer, um die Daten richtig zu parsen und keine unnötigen Dinge zu verwenden. Ein ViewModel beinhaltet normalerweise mehr Dinge als die, die in einer Form nachher übertragen werden (zB Länder-Auswahllisten etc).
Das SubmitModel darf nirgends im POST-Inhalt vor kommen. Wenn es das doch tut, dann stimmt was am ganzen Workflow nicht. Es dürfen nur die Variablen-Namen und deren Inhalte übertragen werden.
Alles andere kapiert der ModelBinder von alleine.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo zusammen,
@Abt: Ja, die Sachen habe ich von dir übernommen. Fuhr bis hierher auch ganz gut damit.
Der Ansatz mit dem CheckBox-Result ist interessant. Hast du dann zusätzlich ein Hidden-Field, was du mit jQuery dann setzt beim Click-Event der Checkbox und prüfst das dann beim validieren ab und setzt eben "YES" oder "NO", oder wie darf ich dein Vorgehen verstehen?
Gruss
Coffeebean
EDIT: Okay, hat sich erledigt. Das mti Javascript und dem Checkbox-Result funktioniert gut. Danke. Wieder was gelernt 😉 Danke.
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Um Wörter zu sparen Copy aus meim Code:
namespace ABCode.Utilities.WebUtilities.SubmitHelpers
{
public enum MVCCheckBoxSubmitValue
{
OFF = 0,
ON = 1,
}
}
public class NewSubmitModel : SubmitModelBase
{
public MVCCheckBoxSubmitValue CookieLawAccepted { get; set; }
}
[HttpPost]
public ActionResult NewUser( NewSubmitModel submitModel )
{
// Ansonsten findet hier KEIN manuelles Mapping statt!
}
<input type="checkbox" id="CookieLawAccepted" name="CookieLawAccepted" />
Hier noch als Tabellenbeispiel:
<input type="checkbox" data-properties-CookieLawAccepted="" id="SelectedUsers_@(userID)_CookieLawAccepted" name="SelectedUsers[@(userID)].CookieLawAccepted" />
public class MassUserEditSubmitModel : SubmitModelBase
{
public IEnumerable<MassUserSubmitItem> SelectedUsers { get; set; }
public class MassUserSubmitItem
{
public MVCCheckBoxSubmitValue CookieLawAccepted { get; set; }
}
}
Funktioniert übrigens auch ohne Javascript-Handler. War ne Fehlinfo ein Post vorher. Es kommt hier eher auf das Verhalten von Enums im Zusammenspiel des Verhalten der Browser an.
Ob's NO oder YES heisst ist eigentlich egal.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
@Abt: auch von mir danke, wieder was gelernt. Warum findet so etwas nicht den Weg in einschlägige Literatur?
--
mfG.
Marcel Eckhoff
Weil ich zu faul bin ein Buch zu schreiben 8)
Lukrativer für mich wäre sowieso die Buchung als Berater statt dem zeitaufwändigen Schreiben eines Buchs 😁
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo Abt,
Weil ich zu faul bin ein Buch zu schreiben
diktiere es halt einfach 😃
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"