Obtener el valor de la casilla de verificación en ASP.NET MVC 4

122

Estoy trabajando en una aplicación ASP.NET MVC 4. Esta aplicación tiene una forma básica. El modelo de mi formulario se parece a lo siguiente:

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

En mi formulario, tengo el siguiente 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>

Cuando publico el formulario, el valor de Recordar en el modelo siempre es falso. Sin embargo, la propiedad Name del modelo tiene un valor. Probé esto estableciendo un punto de interrupción en lo siguiente:

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

No puedo resolverlo. ¿Por qué no se establece el valor de la casilla de verificación?

JQuery Mobile
fuente
¿Se publica con el valor adecuado? ¿Puedes comprobarlo usando Fiddler? Además, no sé si / cómo el valor de la casilla de verificación se traduce en bool.
shahkalpesh
Esto se publica como "activado" o "desactivado" en el formulario. Esto aparentemente no se une bien. Hice una enumeración estúpida para evitar esto.
Yablargo
@Yablargo, no necesitas la enumeración. Simplemente agregue value = "true" a la etiqueta de entrada. Y use un hidden con value = "false" como se muestra a continuación.
greg simpátrico

Respuestas:

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

Generará:

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

Como funciona:

  • Si checkboxpermanece sin marcar, el formulario envía solo el hiddenvalor (falso)
  • Si está marcado, el formulario envía dos campos (falso y verdadero) y conjuntos MVC truepara la boolpropiedad del modelo

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

Esto siempre enviará el valor predeterminado, si está marcado.

desarrollador web
fuente
7
Hola, este comportamiento hace que mi modelo falle en las validaciones, ya que no parece poder averiguar cómo convertir el [verdadero, falso] en un solo valor booleano. ¿Cómo solucionas esto?
Obi
@ObiOnuorah ¿Qué construcción estás usando? ¿Ayudante O marcado html codificado?
desarrollador web
5
Html.EditorFor o Html.CheckBoxFor dan el mismo resultado
Obi
3
Si se usa formCollection, entonces la cadena devuelta para la casilla de verificación como resultado es: "verdadero, falso". ¿Cómo analiza esto? ¿Reemplazar () es la única opción?
Jo Smo
7
Si está agregando sus propias casillas de verificación manualmente, la parte clave es que el valor debe establecerse en "verdadero" ; de lo contrario, el valor predeterminado devuelto por el formulario será " activado " y " activado " no se puede vincular a un bool. que necesita verdadero / falso. (Es posible que vea un error de validación de que el valor "activado" no es válido para el campo ).
Greg
69

Dado que está utilizando Model.Name para establecer el valor. Supongo que está pasando un modelo de vista vacío a la Vista.

Entonces, el valor de Remember es falso y establece el valor del elemento de casilla de verificación en falso. Esto significa que cuando selecciona la casilla de verificación, está publicando el valor "falso" con el formulario. Cuando no lo selecciona, no se publica, por lo que el modelo predeterminado es falso. Es por eso que está viendo un valor falso en ambos casos.

El valor solo se pasa cuando marca la casilla de selección. Para hacer una casilla de verificación en el uso de Mvc

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

o si no desea vincular el modelo a la vista.

@Html.CheckBox("Remember")

Mvc hace algo de magia con un campo oculto para conservar los valores cuando no están seleccionados.

Edite, si realmente tiene aversión a hacer eso y desea generar el elemento usted mismo, puede hacerlo.

<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked=\"checked\"" : "") />
Dan Saltmer
fuente
2
El @Html.CheckboxForcódigo debería ser@Html.CheckBoxFor
fujiiface
Solo uno rápido, ¿cómo lo usarías @(Model.Remember ? "checked=\"checked\"" : "")en un botón de opción? ¿O eso no es posible?
Izzy
Con esa opción, simplemente está manipulando el HTML directamente, un botón de opción es solo type="radio", y seleccionar el que desea seleccionar en el HTML es lo mismo que arriba checked="checked",. La diferencia es que tendrás varios <input />elementos con el mismo nombre. Debe averiguar a cuál de ellos aplicar el HTML adicional.
Dan Saltmer
@Html.CheckBoxFor(x => x.Remember)esto funcionó para mí
JustLearning
15

Usa solo esto

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

En vez de

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

utilizar:

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

Eso le dará una casilla de verificación específicamente para Recordar

Robert
fuente
4

De acuerdo, la casilla de verificación es un poco extraña. Cuando usa el ayudante Html, genera dos entradas de casilla de verificación en el marcado, y ambas se pasan como un par nombre-valor de IEnumerable si está marcado.

Si no está marcado en el marcado, se pasa solo en la entrada oculta que tiene el valor falso.

Entonces, por ejemplo, en el marcado tiene:

      @Html.CheckBox("Chbxs") 

Y en la acción del controlador (asegúrese de que el nombre coincida con el nombre del parámetro de la casilla de verificación en el controlador):

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

Luego, en el controlador puedes hacer algunas cosas como:

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

Sé que esta no es una solución elegante. Espero que alguien de aquí pueda dar algunos consejos.

Yini
fuente
3

Para convertir un valor devuelto de una casilla de verificación en un formulario a una propiedad booleana, utilicé el convertidor de construcción ValueProviderResult en un ModelBinder personalizado.

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

Si trabaja con FormCollection en lugar de modelo, la asignación puede ser tan simple como:

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

Me encontré con un problema similar y pude recuperar el valor de la casilla de verificación usando una casilla de verificación, hiddenfor y un pequeño JQuery así:

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

<script>

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

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

    })

</script>
John Meyer
fuente
2

Esto ha sido un gran dolor y parece que debería ser más sencillo. Aquí está mi configuración y solución.

Estoy usando el siguiente ayudante HTML:

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

Luego, en el controlador, estoy verificando la recopilación de formularios y procesando en consecuencia:

bool activeFlag = collection["ActiveFlag"] == "false" ? false : true;
[modelObject].ActiveFlag = activeFlag;
fujiiface
fuente
De acuerdo, hice esto aún más corto ya user.IsActive = fc["IsActive"] != "false";que todavía me siento sucio por hacer una comparación de cadenas en él.
WildJoe
1

Me acabo de encontrar con esto (¡no puedo creer que no se encienda / apague!)

¡De todos modos!

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

Publicará un valor de "encendido" o "apagado".

Esto NO se vinculará a un booleano, ¡pero puede hacer esta tonta solución!

 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
fuente
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
fuente
3
Hola Surendran y bienvenido a Stack Overflow. Cuando incluya el código, formatéelo para que sea legible. Pero lo que es más importante, es crucial explicar por qué el código incluido aborda la pregunta del OP.
Alex A.
1

Para MVC usando Model. Modelo:

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>

En la función [HttpPost], podemos obtener sus propiedades.

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

Si realmente desea usar HTML simple (por cualquier motivo) y no las extensiones integradas de HtmlHelper, puede hacerlo de esta manera.

En vez de

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

intenta usar

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

Las entradas de casilla de verificación en HTML funcionan de modo que cuando están marcadas, envían el valor, y cuando no están marcadas, no envían nada en absoluto (lo que hará que ASP.NET MVC retroceda al valor predeterminado de la campo, false ). Además, el valor de la casilla de verificación en HTML puede ser cualquier cosa, no solo verdadero / falso, por lo que si realmente lo desea, puede incluso usar una casilla de verificación para un campo de cadena en su modelo.

Si usa el incorporado Html.RenderCheckbox, en realidad genera dos entradas: casilla de verificación y un campo oculto para que se envíe un valor falso cuando la casilla de verificación no está marcada (no solo nada). Eso puede causar algunas situaciones inesperadas, como esta:

Tom Pažourek
fuente
0

Para varias casillas de verificación con el mismo nombre ... Código para eliminar falsos innecesarios:

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

Función

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;

    }      



}

Úselo:

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

fuente
0

Modificar Recuerda así

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

Use bool anulable en el controlador y retroceda a falso en nulo como este

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

En mi caso, no estaba configurando la propiedad del modelo "Recordar" en el método get. Verifique su lógica en el controlador. Puede que estés haciendo lo mismo. ¡Espero que esto ayude!

Nour Lababidi
fuente
0

Leí las otras respuestas y no estaba logrando que funcionara, así que esta es la solución con la que terminé.

Mi formulario usa Html.EditorFor(e => e.Property)para generar la casilla de verificación, y al usarlo FormCollectionen el controlador, esto pasa un valor de cadena de 'true,false'en el controlador.

Cuando manejo los resultados, uso un ciclo para recorrerlos; también uso una InfoPropertyinstancia para representar el valor del modelo actual que se evalúa desde el formulario.

Entonces, en cambio, solo verifico si la cadena devuelta comienza con la palabra 'true'y luego establezco una variable booleana truey la paso al modelo de devolución.

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
fuente