剃刀:如果模型是List<>.然后@ Html.LabelFor创建一个空的"for".场地 [英] Razor: If model is List<> then @Html.LabelFor creates empty "for" field

查看:89
本文介绍了剃刀:如果模型是List<>.然后@ Html.LabelFor创建一个空的"for".场地的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果模型是对象列表,则@Html.LabelFor model => model[i].member)创建一个空的for属性. DisplayName可以正常工作,模型绑定也可以.唯一不起作用的是for属性.

If the model is a list of objects then @Html.LabelFor model => model[i].member) creates an empty for attribute. The DisplayName works properly, model binding also works just fine. The only thing that does not work is the for attribute.

下面有两个版本的MVC代码.前3个代码段适用于无效的模型,控制器和视图组合(模型是列表).第二组包含3个代码段.这次,列表被包装在一个对象中.

Below there are two versions of the MVC code. The first 3 code snippets are for the model, controller and view combination that does not work, (the model is a list). The second set of 3 code snippets work. This time the list is wrapped in an object.

我想念什么?

型号:

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

控制器:

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

查看:

@model List<ModelBinding.Models.ViewModel>
// form code removed for brevity
@for (var i = 0; i < Model.Count; i++) {
    <div class="form-group">
        @Html.LabelFor(model => model[i].ClickMe)
        <div class="col-md-10">
            @Html.EditorFor(model => model[i].ClickMe, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model[i].ClickMe, "", new { @class = "text-danger" })
        </div>
    </div>
}

标记:

<div class="form-group">
    <label for="">ClickMe</label>
    <div class="col-md-10">
        <input name="[0].ClickMe" class="form-control check-box" type="checkbox" checked="checked" value="true" data-val-required="The ClickMe field is required." data-val="true"><input name="[0].ClickMe" type="hidden" value="false">
        <span class="field-validation-valid text-danger" data-valmsg-replace="true" data-valmsg-for="[0].ClickMe"></span>
    </div>
</div>

请注意,for字段为空,并且输入没有id字段(在"for"字段中使用了一个).

Please notice that the for field is empty and the input has no id field (that one is used in the "for" field).

我创建了一个包含对象列表的包装器模型,修改了控制器和视图,然后工作正常.在这种情况下,"for"字段将正确填写,并且一切正常.

I have created a wrapper model that contains a list of objects, modified the controller and view and then it works just fine. In this case the "for" field is filled in correctly and everything works as expected.

public class ListWrapper {
    public List<ViewModel> ViewModels { get; set; }
}

查看:

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

标记:

<div class="form-group">
    <label for="ViewModels_0__ClickMe">ClickMe</label>
    <div class="col-md-10">
        <input name="ViewModels[0].ClickMe" class="form-control check-box" id="ViewModels_0__ClickMe" type="checkbox" checked="checked" value="true" data-val-required="The ClickMe field is required." data-val="true"><input name="ViewModels[0].ClickMe" type="hidden" value="false">
        <span class="field-validation-valid text-danger" data-valmsg-replace="true" data-valmsg-for="ViewModels[0].ClickMe"></span>
    </div>
</div>

因此,仅当模型是对象列表时,for属性似乎为空.

So, it seems that the for attribute is empty only if the model is a list of objects.

这是一个已知问题吗?还是我想念什么?

Is this a known issue? Or maybe I'm missing something?

推荐答案

此行为是框架符合HTML-4规范的结果.在HTML-4中

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

ID和NAME令牌必须以字母([A-Za-z])开头,后可以跟任意数量的字母,数字([0-9]),连字符(-"),下划线("_),冒号(":)和点号(".).

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 (".").

当模型是集合并且使用@Html.EditorFor(m => m[i].SomeProperty)生成表单控件时,该方法将基于属性名称生成nameid属性.在这种情况下,集合中第一项的name属性将为

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"

但是为了避免与jQuery选择器发生冲突,该方法在生成id属性时会用下划线_替换.[]字符,这会导致

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"

但是因为根据HTML-4规范这是无效的,所以帮助程序不会将其输出到html中.

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

使用@Html.LabelFor()时也是如此(由于关联的表单控件将没有id属性,因此for属性的值不会在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.

请注意,在HTML-5中,id属性将是有效的,因此希望以后可以删除此行为.

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

您的第二个示例有效,因为id="ViewModels_0__ClickMe以字母开头,因此有效.

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

旁注:例如,您可以通过生成自己的id属性来解决第一个问题

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) } })

这篇关于剃刀:如果模型是List&lt;&gt;.然后@ Html.LabelFor创建一个空的"for".场地的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆