Laden...

MVC4 und CheckBox

Erstellt von Coffeebean vor 10 Jahren Letzter Beitrag vor 10 Jahren 2.660 Views
Coffeebean Themenstarter:in
2.207 Beiträge seit 2011
vor 10 Jahren
MVC4 und CheckBox

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

S
417 Beiträge seit 2008
vor 10 Jahren

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.

Coffeebean Themenstarter:in
2.207 Beiträge seit 2011
vor 10 Jahren

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

S
417 Beiträge seit 2008
vor 10 Jahren

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.

Coffeebean Themenstarter:in
2.207 Beiträge seit 2011
vor 10 Jahren

Hallo Sarc,

der generierte HTML-Code schaut so aus


<input data-val="true" data-val-required="Das Feld &quot;Asdf&quot; 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

S
417 Beiträge seit 2008
vor 10 Jahren

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" />
}
Coffeebean Themenstarter:in
2.207 Beiträge seit 2011
vor 10 Jahren

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 😉

S
417 Beiträge seit 2008
vor 10 Jahren

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.

P
48 Beiträge seit 2005
vor 10 Jahren

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

Coffeebean Themenstarter:in
2.207 Beiträge seit 2011
vor 10 Jahren

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

16.835 Beiträge seit 2008
vor 10 Jahren

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.

Coffeebean Themenstarter:in
2.207 Beiträge seit 2011
vor 10 Jahren

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.

16.835 Beiträge seit 2008
vor 10 Jahren

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.

P
48 Beiträge seit 2005
vor 10 Jahren

@Abt: auch von mir danke, wieder was gelernt. Warum findet so etwas nicht den Weg in einschlägige Literatur?

--
mfG.
Marcel Eckhoff

16.835 Beiträge seit 2008
vor 10 Jahren

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 😁

6.911 Beiträge seit 2009
vor 10 Jahren

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!"