Razor: Si model est List , alors @ Html.LabelFor crée un champ «for» vide

Si le modèle est une liste d’objects, @Html.LabelFor model => model[i].member) crée un atsortingbut vide for . DisplayName fonctionne correctement, la liaison de modèle fonctionne également très bien. La seule chose qui ne fonctionne pas est l’atsortingbut for .

Vous trouverez ci-dessous deux versions du code MVC. Les 3 premiers extraits de code concernent la combinaison modèle, contrôleur et vue qui ne fonctionne pas (le modèle est une liste). La deuxième série de 3 extraits de code fonctionne. Cette fois, la liste est encapsulée dans un object.

Qu’est-ce que je rate?

Modèle:

 public class ViewModel { public bool ClickMe { get; set; } } 

Manette:

 public ActionResult LabelForViewModel() { List model = new List() { new ViewModel() { ClickMe = true} }; return View(model); } 

Vue:

 @model List // form code removed for brevity @for (var i = 0; i < Model.Count; i++) { 
@Html.LabelFor(model => model[i].ClickMe)
@Html.EditorFor(model => model[i].ClickMe, new { htmlAtsortingbutes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model[i].ClickMe, "", new { @class = "text-danger" })
}

Balisage:

 

Veuillez noter que le champ for est vide et que l’entrée n’a pas de champ id (celui-ci est utilisé dans le champ “for”).

J’ai créé un modèle de wrapper contenant une liste d’objects, modifié le contrôleur et la vue, puis tout fonctionne correctement. Dans ce cas, le champ “pour” est rempli correctement et tout fonctionne comme prévu.

 public class ListWrapper { public List ViewModels { get; set; } } 

Vue:

 @for (var i = 0; i < Model.ViewModels.Count; i++) { 
@Html.LabelFor(model => model.ViewModels[i].ClickMe)
@Html.EditorFor(model => model.ViewModels[i].ClickMe, new { htmlAtsortingbutes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ViewModels[i].ClickMe, "", new { @class = "text-danger" })
}

Balisage:

 

Ainsi, il semble que l’atsortingbut for soit vide que si le modèle est une liste d’objects.

est-ce un problème connu? Ou peut-être que je manque quelque chose?

Ce comportement est le résultat de la structure conforme aux spécifications HTML-4. En HTML-4

Les jetons ID et NOM doivent commencer par une lettre ([A-Za-z]) et peuvent être suivis par un nombre quelconque de lettres, chiffres ([0-9]), traits d’union (“-“), traits de soulignement (“_”) , deux points (“:”) et périodes (“.”).

Lorsque votre modèle est une collection et que vous utilisez @Html.EditorFor(m => m[i].SomeProperty) pour générer des contrôles de formulaire, la méthode génère des atsortingbuts name et id fonction du nom de la propriété. Dans ce cas, l’atsortingbut name du premier élément de la collection sera

 name="[0].SomeProperty" 

mais pour éviter les conflits avec les sélecteurs jQuery, la méthode est remplacée . , [ et ] caractères avec un trait de soulignement _ lors de la génération de l’atsortingbut id qui aurait pour résultat

 id="_0__SomeProperty" 

mais comme il n’est pas valide selon la spécification HTML-4, l’assistant ne le renvoie pas au format HTML.

La même chose s’applique lors de l’utilisation de @Html.LabelFor() (étant donné que le contrôle de formulaire associé n’aura pas d’atsortingbut id , la valeur de l’atsortingbut for n’est pas sortie dans le code HTML.

Notez que dans HTML-5, l’atsortingbut id serait valide, donc ce comportement sera abandonné dans le futur.

Votre deuxième exemple fonctionne car id="ViewModels_0__ClickMe ” commence par une lettre et est donc valide.

Note latérale: Vous pouvez résoudre le premier problème en générant vos propres atsortingbuts d’ id , par exemple

 @Html.LabelFor(model => model[i].ClickMe, new { for = ssortingng.Format("item{0}", i) }) @Html.EditorFor(model => model.ViewModels[i].ClickMe, new { htmlAtsortingbutes = new { @class = "form-control", id = ssortingng.Format("item{0}", i) } }) 

La déclaration @model affecte l’object de modèle à la variable Model (notez le captial ‘M’). Mais ensuite, vous lisez un model qui n’a pas été atsortingbué.

Essaye ça:

  @model List // form code removed for brevity @for (var i = 0; i < Model.Count; i++) { 
@Html.LabelFor(model => Model[i].ClickMe)
@Html.EditorFor(model => Model[i].ClickMe, new { htmlAtsortingbutes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => Model[i].ClickMe, "", new { @class = "text-danger" })
}

Cela n’explique pas pourquoi votre deuxième exemple fonctionne du tout, mais bon, essayez ceci.