web-dev-qa-db-fra.com

ASP.NET MVC 4 remplace le nom et l'ID html émis

J'essaie de changer le nom émis de l'entrée html créée par @Html.HiddenFor.

Le code que j'utilise ceci:

@Html.HiddenFor(e => e.SomeProperty, new { @id = "some_property", @name = "some_property" }

Maintenant, cela fonctionne pour le id, mais cela ne fonctionne pas pour le nom. Maintenant, je ne me soucie plus vraiment du id maintenant, j'ai besoin du name pour changer, car c'est celui qui est posté sur le serveur cible.

Y a-t-il

  • Une propriété que je peux appliquer sur SomeProperty dans mon modèle?
  • Un chemin dans le Html.HiddenFor pour remplacer la propriété name?

Ou suis-je coincé pour faire un simple <input ...> par la main?

52
Snake

Vous devez utiliser le Html.Hidden (ou écrire le <input ...> à la main) au lieu de Html.HiddenFor

@Html.Hidden("some_property", Model.SomeProperty, new { @id = "some_property" })

Le but des assistants fortement typés (par exemple celui dont le nom se termine "Pour" comme HiddenFor) est de deviner le nom d'entrée pour vous à partir de l'expression fournie. Donc, si vous voulez avoir un nom d'entrée "personnalisé", vous pouvez toujours utiliser les assistants habituels comme Html.Hidden où vous pouvez définir explicitement le nom.

réponse d'unjuken est faux car il génère invalide HTML.

L'utilisation de cette solution génère [~ # ~] deux [~ # ~] name attributs:

<input  Name="some_property"  name="SomeProperty" id="some_property" type="hidden" value="test" /> 

Vous aurez donc Name="some_property" [~ # ~] et [~ # ~] name="SomeProperty" qui est [~ # ~] non valide [~ # ~] HTML car une entrée ne peut avoir que [ ~ # ~] un [~ # ~] name attribut! (bien que la plupart des browers prennent le premier Name="some_property" et ne vous souciez pas du second ...)

105
nemesv

Si tu utilises:

@ Html.HiddenFor (e => e.SomeProperty, new {@id = "some_property", @Name = "some_property"});

Notez le "N" majuscule dans @Name. Ça va marcher.

36
unjuken

J'étais curieux de savoir pourquoi remplacer spécifiquement l'attribut name ne fonctionnerait pas. Sauf si je l'ai capitalisé (c'est-à-dire new {@Name = 'somename'}), alors cela ne semble pas fonctionner. Comme d'autres l'ont souligné, cela ne fonctionne que parce qu'il génère des attributs de nom dupliqués et Chrome le nettoie.

J'ai regardé le dernier code source MVC pour comprendre ce qui se passe. Considérez l'extrait suivant de la méthode GenerateInput dans DefaultHtmlGenerator.cs:

var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);
if (string.IsNullOrEmpty(fullName))
{
    throw new ArgumentException(
    ...
}

var inputTypeString = GetInputTypeString(inputType);
var tagBuilder = new TagBuilder("input");
tagBuilder.TagRenderMode = TagRenderMode.SelfClosing;
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("type", inputTypeString);
tagBuilder.MergeAttribute("name", fullName, replaceExisting: true);

Nous pouvons voir ici, le problème est que, quelle que soit la propriété de nom que vous fournissez, elle sera remplacée par le dernier appel à MergeAttribute, qui utilisera la logique assignée à la variable fullName à partir de la méthode GetFullHtmlFieldName.

Je comprends en quelque sorte pourquoi ils appliquent ce comportement, devinant que cela a quelque chose à voir avec le contrôle des noms utilisés dans la publication pour garantir qu'il fonctionne avec le classeur de modèles.

Dans tous les cas, pour y arriver, je dis simplement construire manuellement l'élément d'entrée et ne pas utiliser l'assistant de vue de rasoir.

3
sovemp

n'a jamais fonctionné pour moi (aspnet.core)

J'ai utilisé ordinaire

<input type="hidden" id="@myid" name="@myname" value="@Model.prop" />

et a travaillé comme un charme. Pas besoin de HtmlHelper HiddenForModel.

0
Carl Verret