Ottenere il valore della casella di controllo in ASP.NET MVC 4


122

Sto lavorando su un'app ASP.NET MVC 4. Questa app ha una forma di base. Il modello per il mio modulo è simile al seguente:

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

Nella mia forma, ho il seguente HTML.

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

Quando inserisco il modulo, il valore Ricorda nel modello è sempre falso. Tuttavia, la proprietà Name nel modello ha un valore. L'ho testato impostando un punto di interruzione nel seguente:

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

Non riesco a capirlo. Perché il valore della casella di controllo non viene impostato?


Viene pubblicato con il valore corretto? Puoi verificarlo usando Fiddler? Inoltre, non so se / come il valore della casella di controllo si traduca in bool.
shahkalpesh

Questo viene pubblicato come "attivato" o "disattivato" nel modulo. Questo apparentemente non si lega bene. Ho fatto una stupida enumerazione per evitarlo.
Yablargo

@ Yablargo, non hai bisogno dell'enumerazione. Basta aggiungere value = "true" al tag di input. E usa un nascosto con valore = "false" come mostrato di seguito.
simpatrico greg

Risposte:


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

Genererà:

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

Come funziona:

  • Se checkboxrimane deselezionato, il modulo invia solo il filehidden valore (false)
  • Se selezionato, il modulo invia due campi (falso e vero) e gli insiemi MVC trueper la boolproprietà del modello

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

Questo invierà sempre il valore predefinito, se selezionato.


7
Salve, questo comportamento fa sì che il mio modello fallisca le convalide in quanto non sembra essere in grado di capire come trasformare il [vero, falso] in un singolo valore booleano. Come aggiri questo problema?
Obi

@ObiOnuorah Che tipo di costruzione stai usando? Helper O markup html hardcoded?
webdeveloper

5
Html.EditorFor o Html.CheckBoxFor danno lo stesso risultato
Obi

3
Se viene utilizzato formCollection, la stringa restituita per la casella di controllo come risultato è: "true, false". Come lo analizzi? Sostituisci () è l'unica opzione?
Jo Smo

7
Se stai aggiungendo manualmente le tue caselle di controllo, la parte fondamentale è che il valore deve essere impostato su "true" , altrimenti il valore predefinito restituito dal modulo sarà "on" e "on" non può essere associato a un bool che necessita di vero / falso. (Potresti visualizzare un errore di convalida che indica che il valore "on" non è valido per il campo .)
Greg

69

Poiché stai usando Model.Name per impostare il valore. Presumo che tu stia passando un modello di visualizzazione vuoto alla visualizzazione.

Quindi il valore per Ricorda è falso e imposta il valore sull'elemento casella di controllo su falso. Ciò significa che quando selezioni la casella di controllo, stai registrando il valore "false" con il modulo. Quando non lo selezioni, non viene pubblicato, quindi il modello diventa falso per impostazione predefinita. Ecco perché in entrambi i casi stai vedendo un valore falso.

Il valore viene passato solo quando si seleziona la casella di selezione. Per fare una checkbox in Mvc usa

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

o se non desideri associare il modello alla vista.

@Html.CheckBox("Remember")

Mvc fa qualche magia con un campo nascosto per rendere persistenti i valori quando non sono selezionati.

Modifica, se hai davvero un'avversione a farlo e vuoi generare l'elemento da solo, potresti farlo.

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

2
Il @Html.CheckboxForcodice dovrebbe effettivamente essere@Html.CheckBoxFor
fujiiface

Solo uno veloce come useresti @(Model.Remember ? "checked=\"checked\"" : "")su un pulsante di opzione? o non è possibile
Izzy

Con questa opzione si sta solo manipolando direttamente il codice HTML, un pulsante di scelta è solo type="radio", e selezionando quello desiderato selezionato nel HTML è lo stesso come sopra, checked="checked". La differenza è che avrai più <input />elementi con lo stesso nome. Devi capire a quale di quelli applicare l'HTML aggiuntivo.
Dan Saltmer

@Html.CheckBoxFor(x => x.Remember)questo ha funzionato per me
JustLearning

15

Usa solo questo

$("input[type=checkbox]").change(function () {
    if ($(this).prop("checked")) {
        $(this).val(true);
    } else {
        $(this).val(false);
    }
});

Oppure:$(this).val($(this).is(":checked"));
Norman

5

Invece di

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

uso:

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

Questo ti darà una casella di controllo specifica per Ricorda


4

Ok, la casella di controllo è un po 'strana. Quando si utilizza l'helper Html, vengono generati due input di caselle di controllo sul markup ed entrambi vengono passati come coppia nome-valore di IEnumerable se è selezionata.

Se non è controllato nel markup, viene passato solo all'input nascosto che ha valore false.

Quindi ad esempio sul markup hai:

      @Html.CheckBox("Chbxs") 

E nell'azione del controller (assicurati che il nome corrisponda al nome del parametro della casella di controllo sul controller):

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

Quindi nel controller puoi fare alcune cose come:

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

So che questa non è una soluzione elegante. Spero che qualcuno qui possa dare alcuni suggerimenti.


3

Per convertire un valore restituito da una casella di controllo in un modulo in una proprietà booleana, ho utilizzato il convertitore di build ValueProviderResult in un ModelBinder personalizzato.

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

3

Se si lavora con FormCollection anziché con il modello, l'assegnazione può essere semplice come:

MyModel.Remember = fields["Remember"] != "false";

2

Mi sono imbattuto in un problema simile e sono stato in grado di recuperare il valore della casella di controllo utilizzando una casella di controllo, hiddenfor e un piccolo JQuery in questo modo:

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

<script>

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

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

    })

</script>

2

Questo è stato un grande dolore e sembra che dovrebbe essere più semplice. Ecco la mia configurazione e soluzione.

Sto usando il seguente helper HTML:

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

Quindi, nel controller, controllo la raccolta e l'elaborazione dei moduli di conseguenza:

bool activeFlag = collection["ActiveFlag"] == "false" ? false : true;
[modelObject].ActiveFlag = activeFlag;

D'accordo, l'ho reso ancora più breve perché user.IsActive = fc["IsActive"] != "false";mi sento ancora sporco per aver fatto un confronto di stringhe su di esso.
WildJoe

1

Mi sono appena imbattuto in questo (non riesco a credere che non si vincoli / disabiliti!)

In ogni modo!

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

Pubblicherà un valore di "on" o "off".

Questo NON si legherà a un booleano, ma puoi fare questa sciocca soluzione alternativa!

 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; }
}

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);

    });

3
Ciao Surendran e benvenuto in Stack Overflow. Quando includi il codice, formattalo per leggibilità. Ma ancora più importante, è fondamentale spiegare perché il codice incluso risolve la domanda dell'OP.
Alex A.

1

Per l'MVC che utilizza Model. Modello:

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>

Nella funzione [HttpPost] possiamo ottenere le sue proprietà.

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

1

Se vuoi davvero usare HTML semplice (per qualsiasi motivo) e non le estensioni HtmlHelper incorporate, puoi farlo in questo modo.

Invece di

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

prova a usare

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

Gli input delle caselle di controllo in HTML funzionano in modo che quando vengono selezionati, inviano il valore e, quando non sono selezionati, non inviano nulla (il che causerà il fallback di ASP.NET MVC al valore predefinito del campo, false ). Inoltre, il valore della casella di controllo in HTML può essere qualsiasi cosa non solo vero / falso, quindi se lo desideri davvero, puoi persino utilizzare una casella di controllo per un campo stringa nel tuo modello.

Se usi il file Html.RenderCheckbox , in realtà restituisce due input: casella di controllo e un campo nascosto in modo che venga inviato un valore falso quando la casella di controllo è deselezionata (non solo niente). Ciò potrebbe causare alcune situazioni impreviste, come questa:


0

Per più caselle di controllo con lo stesso nome ... Codice per rimuovere false non necessarie:

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

Funzione

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;

    }      



}

Usalo:

int x = 0;
foreach (var detail in d_prix){
factured.taxe1 = (d_taxe1[x] == "true") ? true : false;
x++;
}

0
public ActionResult Index(string username, string password, string rememberMe)
{
   if (!string.IsNullOrEmpty(username))
   {
      bool remember = bool.Parse(rememberMe);
      //...
   }
   return View();
}

0

Modifica Ricorda in questo modo

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

Usa nullable bool nel controller e fallback su false su null come questo

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

0

Nel mio caso non stavo impostando la proprietà del modello "Ricorda" nel metodo get. Controlla la tua logica nel controller. Potresti fare lo stesso. Spero che questo aiuto!


0

Ho letto le altre risposte e non riuscivo a farlo funzionare, quindi ecco la soluzione che ho trovato.

Il mio modulo utilizza Html.EditorFor(e => e.Property)per generare la casella di controllo e, utilizzando FormCollectionnel controller, passa un valore stringa di'true,false' nel controller.

Quando gestisco i risultati, utilizzo un ciclo per visualizzarli in modo ciclico: utilizzo anche un file InfoProperty un'istanza per rappresentare il valore del modello corrente valutato dal modulo.

Quindi, invece, controllo solo se la stringa restituita inizia con la parola, 'true'quindi imposto una variabile booleana a truee la passo nel modello di ritorno.

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);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.