Abrufen des Kontrollkästchenwerts in ASP.NET MVC 4

122

Ich arbeite an einer ASP.NET MVC 4-App. Diese App hat eine Grundform. Das Modell für mein Formular sieht folgendermaßen aus:

public class MyModel
{
    public string Name { get; set; }
    public bool Remember { get; set; }
}

In meinem Formular habe ich den folgenden HTML-Code.

<input id="Name" name="Name" type="text" value="@Model.Name" />
<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />
<label for="Remember">&nbsp;Remember Me?</label>

Wenn ich das Formular poste, ist der Wert "Merken" im Modell immer falsch. Die Name-Eigenschaft im Modell hat jedoch einen Wert. Ich habe dies getestet, indem ich im Folgenden einen Haltepunkt festgelegt habe:

[HttpPost]
public ActionResult MyAction(MyModel model)
{
  Console.WriteLine(model.Remember.ToString());
}

Ich kann es nicht herausfinden. Warum wird der Checkbox-Wert nicht gesetzt?

JQuery Mobile
quelle
Wird es mit dem richtigen Wert veröffentlicht? Können Sie das mit Fiddler überprüfen? Außerdem weiß ich nicht, ob / wie der Wert des Kontrollkästchens in bool übersetzt wird.
Shahkalpesh
Dies wird im Formular als "Ein" oder "Aus" angezeigt. Dies ist anscheinend nicht richtig. Ich habe eine dumme Aufzählung gemacht, um dies zu vermeiden.
Yablargo
@ Yablargo, du brauchst die Aufzählung nicht. Fügen Sie dem Eingabe-Tag einfach value = "true" hinzu. Und verwenden Sie ein verstecktes mit dem Wert = "false", wie unten gezeigt.
sympatric greg

Antworten:

213
@Html.EditorFor(x => x.Remember)

Wird generieren:

<input id="Remember" type="checkbox" value="true" name="Remember" />
<input type="hidden" value="false" name="Remember" />

Wie funktioniert es:

  • Wenn das checkboxKontrollkästchen nicht aktiviert ist, sendet das Formular nur den hiddenWert (false).
  • Wenn diese Option aktiviert, dann sendet das Formular zwei Felder (false und true) und MVC - Sets truefür das Modell der boolEigenschaft

<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

Dies sendet immer den Standardwert, wenn aktiviert.

Web-Entwickler
quelle
7
Hallo, dieses Verhalten führt dazu, dass mein Modell die Validierung nicht besteht, da es nicht in der Lage zu sein scheint, herauszufinden, wie das [wahre, falsche] in einen einzelnen booleschen Wert umgewandelt werden kann. Wie umgehen Sie das?
Obi
@ObiOnuorah Welche Konstruktion verwendest du? Helfer ODER fest codiertes HTML-Markup?
Webentwickler
5
Html.EditorFor oder Html.CheckBoxFor gibt entweder das gleiche Ergebnis
Obi
3
Wenn formCollection verwendet wird, lautet die für das Kontrollkästchen zurückgegebene Zeichenfolge als Ergebnis: "true, false". Wie analysiert man das? Ist Replace () die einzige Option?
Jo Smo
7
Wenn Sie Ihre eigenen Kontrollkästchen manuell hinzufügen, sollte der Wert auf "true" gesetzt werden. Andernfalls lautet der vom Formular zurückgegebene Standardwert "on" und "on" kann nicht an einen Bool gebunden werden was wahr / falsch braucht. (Möglicherweise wird ein Validierungsfehler angezeigt, bei dem der Wert "Ein" für das Feld nicht gültig ist .)
Greg
69

Da Sie Model.Name verwenden, um den Wert festzulegen. Ich gehe davon aus, dass Sie ein leeres Ansichtsmodell an die Ansicht übergeben.

Der Wert für Remember ist also false und setzt den Wert für das Kontrollkästchenelement auf false. Dies bedeutet, dass Sie beim Aktivieren des Kontrollkästchens den Wert "false" im Formular veröffentlichen. Wenn Sie es nicht auswählen, wird es nicht veröffentlicht, sodass das Modell standardmäßig false ist. Aus diesem Grund wird in beiden Fällen ein falscher Wert angezeigt.

Der Wert wird nur übergeben, wenn Sie das Auswahlfeld aktivieren. Um ein Kontrollkästchen in Mvc zu aktivieren, verwenden Sie

@Html.CheckBoxFor(x => x.Remember)

oder wenn Sie das Modell nicht an die Ansicht binden möchten.

@Html.CheckBox("Remember")

Mvc zaubert mit einem versteckten Feld, um Werte beizubehalten, wenn sie nicht ausgewählt sind.

Bearbeiten, wenn Sie wirklich eine Abneigung dagegen haben und das Element selbst generieren möchten, können Sie dies tun.

<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked=\"checked\"" : "") />
Dan Saltmer
quelle
2
Der @Html.CheckboxForCode sollte eigentlich sein@Html.CheckBoxFor
fujiiface
Nur eine kurze Frage, wie würden Sie @(Model.Remember ? "checked=\"checked\"" : "")ein Optionsfeld verwenden? oder ist das nicht möglich
Izzy
Mit dieser Option bearbeiten Sie den HTML-Code direkt, ein Optionsfeld ist nur type="radio", und die Auswahl des gewünschten HTML-Codes im HTML-Code ist dieselbe wie oben checked="checked". Der Unterschied besteht darin, dass Sie mehrere <input />Elemente mit demselben Namen haben. Sie müssen herausfinden, auf welche davon Sie den zusätzlichen HTML-Code anwenden möchten.
Dan Saltmer
@Html.CheckBoxFor(x => x.Remember)das hat bei mir
funktioniert
15

Verwenden Sie nur dies

$("input[type=checkbox]").change(function () {
    if ($(this).prop("checked")) {
        $(this).val(true);
    } else {
        $(this).val(false);
    }
});
Bekir Topuz
quelle
Oder:$(this).val($(this).is(":checked"));
Norman
5

Anstatt

 <input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

verwenden:

 @Html.EditorFor(x => x.Remember)

Dadurch erhalten Sie ein Kontrollkästchen speziell für Remember

Robert
quelle
4

Okay, das Kontrollkästchen ist ein bisschen komisch. Wenn Sie den HTML-Helfer verwenden, werden zwei Markierungen für das Markup generiert, und beide werden als Name-Wert-Paar von IEnumerable übergeben, wenn diese Option aktiviert ist.

Wenn es im Markup nicht aktiviert ist, wird es nur in der versteckten Eingabe übergeben, die den Wert false hat.

So haben Sie zum Beispiel auf dem Markup:

      @Html.CheckBox("Chbxs") 

Und in der Controller-Aktion (stellen Sie sicher, dass der Name mit dem Kontrollkästchen-Parameternamen auf dem Controller übereinstimmt):

      public ActionResult Index(string param1, string param2,
      string param3, IEnumerable<bool> Chbxs)

Dann können Sie im Controller einige Dinge tun wie:

      if (Chbxs != null && Chbxs.Count() == 2)
        {
            checkBoxOnMarkup = true;
        }
        else
        {
            checkBoxOnMarkup = false;
        }

Ich weiß, dass dies keine elegante Lösung ist. Hoffe, jemand hier kann einige Hinweise geben.

Yini
quelle
3

Um einen von einem Kontrollkästchen in einem Formular zurückgegebenen Wert in eine boolesche Eigenschaft zu konvertieren, habe ich den In-Build-Konverter von ValueProviderResult in einem benutzerdefinierten ModelBinder verwendet.

ValueProviderResult cbValue = bindingContext.ValueProvider.GetValue("CheckBoxName");
bool value = (bool)cbValue.ConvertTo(typeof(bool));
Chris
quelle
3

Wenn Sie mit FormCollection anstatt mit model arbeiten, kann die Zuweisung so einfach sein wie:

MyModel.Remember = fields["Remember"] != "false";
Aaron Carter
quelle
2

Ich bin auf ein ähnliches Problem gestoßen und konnte den Wert des Kontrollkästchens mithilfe eines Kontrollkästchens, versteckt für und kleiner JQuery wie folgt, zurückerhalten:

@Html.CheckBox("isPreferred", Model.IsPreferred)
@Html.HiddenFor(m => m.IsPreferred)

<script>

    $("#isPreferred").change(function () {

        $("#IsPreferred").val($("#isPreferred").val());

    })

</script>
John Meyer
quelle
2

Dies war ein großer Schmerz und scheint einfacher zu sein. Hier ist mein Setup und meine Lösung.

Ich verwende den folgenden HTML-Helfer:

@Html.CheckBoxFor(model => model.ActiveFlag)

Dann überprüfe ich im Controller die Formularerfassung und -verarbeitung entsprechend:

bool activeFlag = collection["ActiveFlag"] == "false" ? false : true;
[modelObject].ActiveFlag = activeFlag;
Fujiiface
quelle
Einverstanden, ich habe dies noch kürzer gemacht, da user.IsActive = fc["IsActive"] != "false";ich mich immer noch schmutzig fühle, wenn ich einen String-Vergleich daran mache.
WildJoe
1

Ich bin gerade darauf gestoßen (ich kann nicht glauben, dass es nicht ein- und ausgeschaltet wird!)

Sowieso!

<input type="checkbox" name="checked" />

Gibt einen Wert von "ein" oder "aus" aus.

Dies wird NICHT an einen Booleschen Wert gebunden , aber Sie können diese dumme Problemumgehung durchführen!

 public class MyViewModel
 {
     /// <summary>
     /// This is a really dumb hack, because the form post sends "on" / "off"
     /// </summary>                    
     public enum Checkbox
     {
        on = 1,
        off = 0
     }
     public string Name { get; set; }
     public Checkbox Checked { get; set; }
}
Yablargo
quelle
1
@Html.EditorFor(x => x.ShowComment)


$(function () {
        // set default value to control on document ready instead of 'on'/'off' 
        $("input[type='checkbox'][name='ShowComment']").val(@Model.ShowComment.ToString().ToLower());
    });

    $("#ShowComment").change(function() {
        // this block sets value to checkbox control for "true" / "false"

        var chkVal = $("input[type='checkbox'][name='ShowComment']").val();
        if (chkVal == 'false') $("input[type='checkbox'][name='ShowComment']").val(true);
        else $("input[type='checkbox'][name='ShowComment']").val(false);

    });
Surendran
quelle
3
Hallo Surendran und willkommen bei Stack Overflow. Wenn Sie Code einfügen, formatieren Sie ihn bitte zur besseren Lesbarkeit. Noch wichtiger ist jedoch, dass erklärt wird, warum der enthaltene Code die Frage des OP behandelt.
Alex A.
1

Für die MVC mit Model. Modell:

public class UserInfo
{
    public string UserID { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public bool RememberMe { get; set; }
}

HTML:

<input type="checkbox" value="true" id="checkbox1" name="RememberMe" checked="@Model.RememberMe"/>
<label for="checkbox1"></label>

In der Funktion [HttpPost] können wir ihre Eigenschaften abrufen.

[HttpPost]
public ActionResult Login(UserInfo user)
{
   //...
   return View(user);
}
Lulala
quelle
1

Wenn Sie wirklich einfaches HTML (aus welchem ​​Grund auch immer) und nicht die integrierten HtmlHelper-Erweiterungen verwenden möchten, können Sie dies auf diese Weise tun.

Anstatt

<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

versuchen Sie es mit

<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked" : "") />

Checkbox-Eingaben in HTML funktionieren so, dass sie beim Aktivieren den Wert senden und wenn sie nicht aktiviert sind, überhaupt nichts senden (was dazu führt, dass ASP.NET MVC auf den Standardwert von zurückfällt Feld, false). Der Wert des Kontrollkästchens in HTML kann auch alles sein, was nicht nur wahr / falsch ist. Wenn Sie es also wirklich wollten, können Sie sogar ein Kontrollkästchen für ein Zeichenfolgenfeld in Ihrem Modell verwenden.

Wenn Sie das integrierte Html.RenderCheckboxKontrollkästchen verwenden, werden tatsächlich zwei Eingaben ausgegeben: das Kontrollkästchen und ein ausgeblendetes Feld, sodass ein falscher Wert gesendet wird, wenn das Kontrollkästchen deaktiviert ist (nicht nur nichts). Dies kann zu unerwarteten Situationen führen:

Tom Pažourek
quelle
0

Für mehrere Kontrollkästchen mit demselben Namen ... Code zum Entfernen unnötiger Fehler:

List<string> d_taxe1 = new List<string>(Request.Form.GetValues("taxe1"));
d_taxe1 = form_checkbox.RemoveExtraFalseFromCheckbox(d_taxe1);

Funktion

public class form_checkbox
{

    public static List<string> RemoveExtraFalseFromCheckbox(List<string> val)
    {
        List<string> d_taxe1_list = new List<string>(val);

        int y = 0;

        foreach (string cbox in val)
        {

            if (val[y] == "false")
            {
                if (y > 0)
                {
                    if (val[y - 1] == "true")
                    {
                        d_taxe1_list[y] = "remove";
                    }
                }

            }

            y++;
        }

        val = new List<string>(d_taxe1_list);

        foreach (var del in d_taxe1_list)
            if (del == "remove") val.Remove(del);

        return val;

    }      



}

Benutze es :

int x = 0;
foreach (var detail in d_prix){
factured.taxe1 = (d_taxe1[x] == "true") ? true : false;
x++;
}
Pascal Carmoni
quelle
0
public ActionResult Index(string username, string password, string rememberMe)
{
   if (!string.IsNullOrEmpty(username))
   {
      bool remember = bool.Parse(rememberMe);
      //...
   }
   return View();
}

quelle
0

Ändern Denken Sie daran

public class MyModel
{
    public string Name { get; set; }
    public bool? Remember { get; set; }
}

Verwenden Sie nullable bool in controller und fallback to false on null wie folgt

[HttpPost]
public ActionResult MyAction(MyModel model)
{
    model.Remember = model.Remember ?? false;
    Console.WriteLine(model.Remember.ToString());
}
irfandar
quelle
0

In meinem Fall habe ich die Modelleigenschaft "Remember" in der get-Methode nicht festgelegt. Überprüfen Sie Ihre Logik in der Steuerung. Sie können das gleiche tun. Ich hoffe diese Hilfe!

Nour Lababidi
quelle
0

Ich habe die anderen Antworten durchgelesen und es nicht ganz zum Laufen gebracht - hier ist die Lösung, mit der ich am Ende fertig war.

Mein Formular verwendet das Html.EditorFor(e => e.Property), um das Kontrollkästchen zu generieren, und bei Verwendung FormCollectionin der Steuerung wird ein Zeichenfolgenwert von 'true,false'in der Steuerung übergeben.

Wenn ich die Ergebnisse verarbeite, verwende ich eine Schleife, um sie zu durchlaufen. Außerdem verwende ich eine InfoPropertyInstanz, um den aktuellen Modellwert darzustellen, der anhand des Formulars bewertet wird.

Stattdessen überprüfe ich einfach, ob die zurückgegebene Zeichenfolge mit dem Wort beginnt, 'true'setze dann eine boolesche Variable auf trueund übergebe diese an das Rückgabemodell.

if (KeyName.EndsWith("OnOff"))
{
    // set on/off flags value to the model instance
    bool keyTrueFalse = false;
    if(values[KeyName].StartsWith("true"))
    {
        keyTrueFalse = true;
    }
    infoProperty.SetValue(processedInfo, keyTrueFalse);
}
C Gil
quelle