Razor: If model is List<> then @Html.LabelFor creates empty “for” field

前端 未结 2 1327
Happy的楠姐
Happy的楠姐 2021-01-20 09:03

If the model is a list of objects then @Html.LabelFor model => model[i].member) creates an empty for attribute. The DisplayName works properly,

2条回答
  •  爱一瞬间的悲伤
    2021-01-20 09:40

    This behavior is the result of the framework complying with HTML-4 specifications. In HTML-4

    ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

    When your model is a collection and you use @Html.EditorFor(m => m[i].SomeProperty) to generate form controls, the method generates name and id attributes based on the name of the property. In this case the name attribute for the first item in the collection will be

    name="[0].SomeProperty"
    

    but to avoid clashes with jQuery selectors, the method replaces ., [, and ] characters with an underscore _ when generating the id attribute which would result in

    id="_0__SomeProperty"
    

    but because this is invalid according to the HTML-4 specification, the helper does not output it in the html.

    The same applies when using @Html.LabelFor() (since the associated form control will not have an id attribute, the value of the for attribute is not output in the html.

    Note that in HTML-5, the id attribute would be valid, so hopefully this behavior will be dropped in the future.

    Your second example works because id="ViewModels_0__ClickMe" begins with a letter and is therefore valid.

    Side note: You could solve the first issue by generating your own id attributes, for example

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

提交回复
热议问题