30 votes

Pourquoi ASP.NET MVC Html.CheckBox génère-t-il deux entrées avec le même nom?

Pourquoi dans le monde de la ligne:

<%= Html.CheckBox("ForSale", Model.Product.ForSale)%> For Sale

résultat dans le code HTML suivant:

<input id="ForSale" name="ForSale" type="checkbox" value="true" />
<input name="ForSale" type="hidden" value="false" />
For Sale

Maintenant, chaque fois que j'ai cocher la case et de l'accès Request.Form["ForSale"], j'obtiens le ridicule réponse de l' "true,false". Suis-je censé analyser cela?

Ce champ caché n'apparaît pas pour les autres HtmlHelper contrôles, alors pourquoi ne fait-il pour Case?

Comment dois-je faire cela stupide "fonction" off? Ou est ce que l' HtmlHelper seulement dépasser son utilité?

Mise à jour

À partir de la réponse ci-dessous, il semble qu'il y a une logique derrière tout cela. J'ai préparé un peu de la méthode d'extension donc je n'ai pas à y penser (merci à @ue-ge-ne):

    public static bool GetCheckBoxValue(this System.Web.HttpRequestBase req, 
                                        string name) {
        return Convert.ToBoolean(req.Form.GetValues(name).First());
    }

38voto

blowdart Points 28735

Il force le champ à être inclus s'il n'est pas coché. Si vous décochez une case, elle n'est pas envoyée dans le cadre de la page - elles ne sont envoyées que si elles sont cochées, puis il y a la valeur true. Le champ caché garantit que false sera envoyé si la case n'est pas cochée, car le champ caché est toujours envoyé.

6voto

Stef Points 1782

J'ai pris une approche différente:

Ne pas utiliser le Html.CheckBoxFor ou Html.Case à cocher de la méthode d'assistance à rendre une case à cocher, mais le rendu à l'aide de html:

<input id="ShowOther" name="ShowOther" value="<%=Model.ShowOther %>" type="checkbox" <% if (Model.ShowOther)  { %>checked="checked"<% } %> />

Et j'ai ajouté un script jQuery qui définit la valeur lorsque la case est cochée/décochée.

<script type="text/javascript">
    $(function() {
        $('#ShowOther').click(function() {
            var checked = $(this).attr('checked');
            if (checked != undefined)
                $(this).val(true);
            else
                $(this).val(false);
        });
    });
</script>

Aussi loin que je puisse tester cela, il semble que la bonne valeur est toujours envoyé au Contrôleur, et pas plus de problèmes avec les "vrai", "faux".

3voto

Brad Gignac Points 699

Voici comment je l'ai fait dans l'une de mes applications. Frustrant, mais cela semble fonctionner.

 public virtual ActionResult Edit(int id, FormCollection values)
{
    SomeObject dbData = _repository.GetSomeObject(id);

    try
    {
        UpdateModel(dbData);
        if (values.GetValues("CheckBoxId").Contains("true")) 
            dbData.SomeBooleanProperty = true;
        else 
            dbData.SomeBooleanProperty = false;

        _repository.Save();

        Session["Success"] = "Successfully edited the part.";
        return RedirectToAction("Index");
    }
    catch
    {
        // Handle validation errors here
        return View(new SomeObjectFormViewModel(dbData));
    }
}
 

J'espère que cela t'aides. Si vous avez des questions complémentaires, laissez simplement un commentaire et je mettrai à jour ma réponse en conséquence.

2voto

CoderDennis Points 7170

Si une Case n'est pas cochée, alors il ne sera pas inclus dans le formulaire de soumission. Donc, cette "fonctionnalité" vous donne un résultat pour chaque Case. Ceux qui ne sont pas cochés seront simplement "faux".

J'ai mis en œuvre mes propres Case fonctions d'assistance qui fonctionnent différemment. La plupart du temps, je ne veux pas seulement vrai ou faux, mais simplement d'une collection de valeurs des cases cochées. Il est idéal pour la sélection de certains éléments par leur id sur lequel effectuer une action. Je ne veux pas être désactivée, même dans la liste.

Vous pouvez prendre un coup d'oeil au code source pour le code html extensions et d'utiliser une structure similaire pour créer votre propre Case méthodes.

http://aspnet.codeplex.com/sourcecontrol/changeset/view/23011?projectName=aspnet#288010

Je poste le mien, mais je ne suis pas en utilisant la norme HtmlHelper classe, de sorte qu'il serait probablement plus à confusion. J'ai ajouté un paramètre de valeur de ma Case fonctions afin que je puisse utiliser l'id de la valeur à la place de "true" ou "false".

2voto

eu-ge-ne Points 17847

Maintenant, chaque fois que je coche la case et accède à Request.Form ["ForSale"], j'obtiens la réponse ridicule de "vrai, faux". Suis-je censé analyser cela?

Essaye ça:

 var ForSale = Convert.ToBoolean(Request.Form.GetValues("ForSale").First());
 

MIS À JOUR:

Que se passe-t-il si dans la prochaine génération MVC, il retournera la valeur dans l'ordre inverse "false, true"? ... - Mastermind

 var ForSale = Request.Form.GetValues("ForSale")
    .Select(x => x.ToUpperInvariant()).Contains("TRUE");

// or

// FormatException can be thrown from Convert.ToBoolean()
var ForSale = Request.Form.GetValues("ForSale")
    .Select(x => Convert.ToBoolean(x)).Contains(true);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X