Je travaille sur une application ASP.NET MVC 4. Cette application a une forme de base. Le modèle de mon formulaire se présente comme suit:
public class MyModel
{
public string Name { get; set; }
public bool Remember { get; set; }
}
Dans mon formulaire, j'ai le code HTML suivant.
<input id="Name" name="Name" type="text" value="@Model.Name" />
<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />
<label for="Remember"> Remember Me?</label>
Lorsque je poste le formulaire, la valeur Remember du modèle est toujours false. Cependant, la propriété Name du modèle a une valeur. J'ai testé cela en définissant un point d'arrêt dans les éléments suivants:
[HttpPost]
public ActionResult MyAction(MyModel model)
{
Console.WriteLine(model.Remember.ToString());
}
Je ne peux pas comprendre. Pourquoi la valeur de la case à cocher n'est-elle pas définie?
@Html.EditorFor(x => x.Remember)
Va générer:
<input id="Remember" type="checkbox" value="true" name="Remember" />
<input type="hidden" value="false" name="Remember" />
Comment ça marche:
checkbox
reste décoché, le formulaire ne soumet que la valeur hidden
(false)true
pour la propriété bool
du modèle<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />
Cela enverra toujours la valeur par défaut, si coché.
Depuis que vous utilisez Model.Name pour définir la valeur. Je suppose que vous passez un modèle de vue vide à la vue.
Ainsi, la valeur de Remember est false et définit la valeur de l'élément checkbox sur false. Cela signifie que lorsque vous cochez ensuite la case, vous publiez la valeur "false" avec le formulaire. Lorsque vous ne le sélectionnez pas, il n'est pas publié. Le modèle par défaut est donc false. C'est pourquoi vous voyez une fausse valeur dans les deux cas.
La valeur n'est transmise que lorsque vous cochez la case de sélection. Pour faire une case à cocher dans Mvc utiliser
@Html.CheckBoxFor(x => x.Remember)
ou si vous ne voulez pas lier le modèle à la vue.
@Html.CheckBox("Remember")
MVC fait de la magie avec un champ caché pour conserver les valeurs quand elles ne sont pas sélectionnées.
Modifier, si vous avez vraiment une aversion pour faire cela et que vous voulez générer l'élément vous-même, vous pouvez le faire.
<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked=\"checked\"" : "") />
Utilisez seulement ceci
$("input[type=checkbox]").change(function () {
if ($(this).prop("checked")) {
$(this).val(true);
} else {
$(this).val(false);
}
});
OK, la case à cocher est un peu bizarre . Lorsque vous utilisez l'assistant HTML, il génère deux entrées de case à cocher sur le balisage, et les deux sont transmises sous forme de paire nom-valeur de IEnumerable si elle est cochée.
S'il n'est pas coché dans le balisage, il n'est transmis que dans l'entrée masquée ayant la valeur false.
Ainsi, par exemple, sur le balisage, vous avez:
@Html.CheckBox("Chbxs")
Et dans l'action du contrôleur (assurez-vous que le nom correspond au nom de la case à cocher param sur le contrôleur):
public ActionResult Index(string param1, string param2,
string param3, IEnumerable<bool> Chbxs)
Ensuite, dans le contrôleur, vous pouvez faire des choses comme:
if (Chbxs != null && Chbxs.Count() == 2)
{
checkBoxOnMarkup = true;
}
else
{
checkBoxOnMarkup = false;
}
Je sais que ce n'est pas une solution élégante. J'espère que quelqu'un ici peut donner des indications.
Pour convertir une valeur renvoyée par une case à cocher d'un formulaire en une propriété booléenne, j'ai utilisé le convertisseur ValueProviderResult's in build dans un ModelBinder personnalisé.
ValueProviderResult cbValue = bindingContext.ValueProvider.GetValue("CheckBoxName");
bool value = (bool)cbValue.ConvertTo(typeof(bool));
Au lieu de
<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />
utilisation:
@Html.EditorFor(x => x.Remember)
Cela vous donnera une case à cocher spécialement pour Remember
J'ai rencontré un problème similaire et j'ai pu récupérer la valeur de la case à cocher en utilisant une case à cocher, hiddenfor et un peu de JQuery comme ceci:
@Html.CheckBox("isPreferred", Model.IsPreferred)
@Html.HiddenFor(m => m.IsPreferred)
<script>
$("#isPreferred").change(function () {
$("#IsPreferred").val($("#isPreferred").val());
})
</script>
@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);
});
Pour le MVC utilisant Model . Model:
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>
Dans la fonction [HttpPost], nous pouvons obtenir ses propriétés.
[HttpPost]
public ActionResult Login(UserInfo user)
{
//...
return View(user);
}
public ActionResult Index(string username, string password, string rememberMe)
{
if (!string.IsNullOrEmpty(username))
{
bool remember = bool.Parse(rememberMe);
//...
}
return View();
}
Pour plusieurs cases à cocher portant le même nom ... Code à supprimer inutile
List<string> d_taxe1 = new List<string>(Request.Form.GetValues("taxe1"));
d_taxe1 = form_checkbox.RemoveExtraFalseFromCheckbox(d_taxe1);
Une fonction
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;
}
}
Utilise le :
int x = 0;
foreach (var detail in d_prix){
factured.taxe1 = (d_taxe1[x] == "true") ? true : false;
x++;
}
Si vous voulez vraiment utiliser du HTML pur (quelle que soit la raison) et non les extensions HtmlHelper intégrées, vous pouvez le faire de cette façon.
Au lieu de
<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />
essayez d'utiliser
<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked" : "") />
Les entrées de case à cocher en HTML fonctionnent de sorte que, lorsqu'elles sont cochées, elles envoient la valeur, et lorsqu'elles ne le sont pas, elles n'envoient rien du tout (ce qui fera que ASP.NET MVC se repliera sur la valeur par défaut du champ, false
). En outre, la valeur de la case à cocher en HTML peut être différente de la valeur vraie/fausse. Par conséquent, si vous le souhaitez vraiment, vous pouvez même utiliser une case à cocher pour un champ de chaîne dans votre modèle.
Si vous utilisez le Html.RenderCheckbox
intégré, il génère en fait deux entrées: une case à cocher et un champ masqué, de sorte qu'une valeur fausse est envoyée lorsque la case à cocher est décochée (et pas simplement rien). Cela peut provoquer des situations inattendues, comme ceci:
Modifier Se souvenir comme ça
public class MyModel
{
public string Name { get; set; }
public bool? Remember { get; set; }
}
Utilisez nullable bool dans le contrôleur et fallback à false sur null comme ceci
[HttpPost]
public ActionResult MyAction(MyModel model)
{
model.Remember = model.Remember ?? false;
Console.WriteLine(model.Remember.ToString());
}
Dans mon cas, je ne définissais pas la propriété de modèle "Remember" dans la méthode get. Vérifiez votre logique dans le contrôleur. Vous faites peut-être la même chose. J'espère que cette aide!
J'ai lu les autres réponses et je n'ai pas bien compris. Voici donc la solution qui m'a été proposée.
Mon formulaire utilise la Html.EditorFor(e => e.Property)
pour générer la case à cocher et, à l'aide de FormCollection
dans le contrôleur, cela transmet la valeur de chaîne 'true,false'
dans le contrôleur.
Lorsque je traite les résultats, j'utilise une boucle pour les parcourir. J'utilise également une instance InfoProperty
pour représenter la valeur du modèle en cours d'évaluation à partir du formulaire.
Au lieu de cela, je vérifie simplement si la chaîne renvoyée commence par Word 'true'
, puis définit une variable booléenne sur true
et la transmet au modèle de retour.
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);
}
Je viens de rencontrer ceci (je ne peux pas croire que ça ne se lie pas on/off!)
En tout cas!
<input type="checkbox" name="checked" />
Publiera une valeur de "on" ou "off".
CeciNE VEUT PASse lier à un booléen, mais vous pouvez faire cette solution de contournement stupide!
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; }
}
Si vous utilisez FormCollection plutôt que le modèle, l’affectation peut être aussi simple que:
MyModel.Remember = fields["Remember"] != "false";