70 votes

ASP.NET MVC : La valeur du champ caché n'est pas rendue en utilisant HtmlHelper.Hidden

Quelque chose de plutôt bizarre se produit avec mon application :

J'ai la propriété suivante dans mon ViewModel :

public int? StakeholderId { get; set; }

Il est affiché dans une vue partielle comme suit :

<%= Html.Hidden("StakeholderId", Model.StakeholderId) %>

Le formulaire est soumis, et l'action du contrôleur approprié génère un identifiant et met à jour le modèle, avant de retourner la même vue avec le modèle mis à jour

Le problème que je rencontre est que le champ caché n'a rien dans son attribut "value" rendu la deuxième fois, même si StakeholderId a maintenant une valeur.

Si je sors simplement la valeur seule, elle apparaît sur la page, donc j'ai réussi à faire afficher la valeur en faisant ceci :

Mais c'est assez étrange que l'aide ne prenne pas la valeur mise à jour ?

(J'utilise jQuery pour soumettre des formulaires et afficher les résultats d'action dans des divs, mais j'ai vérifié et le HTML que je récupère est déjà incorrect avant que jQuery n'agisse dessus, donc je ne pense pas que cela ait beaucoup d'importance)

MISE À JOUR

J'ai depuis découvert que je peux également effacer la clé de ModelState pertinente avant que mon action de contrôleur ne retourne la vue partielle.

60voto

Darin Dimitrov Points 528142

L'aide cherchera d'abord les valeurs POSTées et les utilisera. Comme vous envoyez le formulaire, il reprendra l'ancienne valeur de l'ID. Votre solution de contournement est correcte.

34voto

awrigley Points 6468

ADDENDUM : Formulaires HTML multiples, par exemple, dans une grille

En addendum à cette question, une chose à laquelle il faut faire TRÈS attention est d'avoir plusieurs formulaires sur la même page, par exemple, dans une grille, disons une générée en utilisant Ajax.BeginForm.

Vous pourriez être tenté d'écrire quelque chose du genre :

@foreach (var username in Model.TutorUserNames)
        {

                    @Html.ActionLink(username, MVC.Admin.TutorEditor.Details(username))

                    @using (Ajax.BeginForm("DeleteTutor", "Members",
                        new AjaxOptions
                        {
                            UpdateTargetId = "AdminBlock",
                            OnBegin = "isValidPleaseWait",
                            LoadingElementId = "PleaseWait"
                        },
                        new { name = "DeleteTutorForm", id = "DeleteTutorForm" }))
                    {    

                        @Html.Hidden("TutorName", username)
                    }

        }

La ligne problématique ici est la suivante :

@Html.Hidden("TutorName", username)

... et avez l'intention d'utiliser TutorName comme paramètre de votre action. Par exemple :

public virtual ActionResult DeleteTutor(string TutorName){...}

Si vous le faites, la mauvaise surprise qui vous attend est que Html.Hidden("TutorName", username) va, comme l'explique Darin Dimitrov, rendre la dernière valeur postée. Autrement dit, indépendamment de votre boucle, TOUS les éléments seront rendus avec le TutorName du dernier tuteur supprimé !

Le truc, en syntaxe Razor, est de remplacer l'appel à @Html.Hidden par une balise d'entrée explicite :

Cela fonctionne comme prévu.

Autrement dit :

NE JAMAIS, JAMAIS UTILISER Html.Hidden POUR PASSER UN PARAMÈTRE À VOS ACTIONS LORSQUE VOUS UTILISEZ PLUSIEURS FORMULAIRES DANS UNE GRILLE !!!

Avertissement Final :

Lors de la construction de votre balise d'entrée cachée, vous devez inclure à la fois le nom et l'identifiant, définis à la même valeur, sinon, en ce moment (février 2011), cela ne fonctionnera pas correctement. Surtout pas dans Google Chrome. Tout ce que vous obtiendrez est un paramètre nul retourné si vous n'avez qu'un identifiant et aucun attribut de nom.

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