剃刀:如果模型列表与LT;>然后@ Html.LabelFor创建emtpy"为"领域 [英] Razor: If model is List<> then @Html.LabelFor creates emtpy "for" field
问题描述
如果该模型对象的列表,然后 @ Html.LabelFor模型=>模型[I]。成员)
创建一个空的为
属性。
中的显示名称正常工作,模型还结合工作得很好。不工作的唯一的事情是为
属性。
下面有MVC的代码的两个版本。前3个代码段为模型,控制器和视图组合不起作用,(该模型是一个列表)。第二组3代码片段的工作。这一次的名单被包裹在一个对象。
我在想什么?
模型:
公共类视图模型{
公布尔ClickMe {搞定;组; }
}
控制器:
公众的ActionResult LabelForViewModel(){
名单,LT;视图模型>模型=新的List<视图模型>(){
新视图模型(){ClickMe =真}
};
返回查看(模型);
}
查看:
@model名单< ModelBinding.Models.ViewModel>为简便起见
@for删除
//形式的代码(VAR I = 0; I< Model.Count;我++){
< DIV CLASS =表单组>
@ Html.LabelFor(型号=>模型[I] .ClickMe)
< DIV CLASS =COL-MD-10>
@ Html.EditorFor(型号=>模型[I] .ClickMe,新{htmlAttributes = {新@class =表格控}})
@ Html.ValidationMessageFor(型号= GT;模型[I] .ClickMe,新{@class =TEXT-危险})
< / DIV>
< / DIV>
}
标记:
< DIV CLASS =表单组>
<标签=> ClickMe< /标签>
< DIV CLASS =COL-MD-10>
<输入名称=[0] .ClickMe级=的形式控制复选框TYPE =复选框检查=选中价值=真实数据-VAL-所需=的ClickMe字段是必须的。数据-VAL =真正的><输入名称=[0] .ClickMe类型=隐藏值=假>
<跨度类=现场验证,有效文本危险数据valmsg替换=真正的数据valmsg换=[0] .ClickMe>< / SPAN>
< / DIV>
< / DIV>
请注意,在现场为空,且输入有没有id字段(一个是用在在供字段)。
我已经创建了一个包含对象列表的包装模式,修改了控制器和视图,然后它工作得很好。在这种情况下,为字段填写正确,一切都按预期工作。
公共类ListWrapper {
公开名单<视图模型> {的ViewModels获得;组; }
}
查看:
@for(VAR I = 0; I< Model.ViewModels.Count;我++){
< DIV CLASS =表单组>
@ Html.LabelFor(型号=> model.ViewModels [I] .ClickMe)
< DIV CLASS =COL-MD-10>
@ Html.EditorFor(型号=> model.ViewModels [I] .ClickMe,新{htmlAttributes = {新@class =表格控}})
@ Html.ValidationMessageFor(型号= > model.ViewModels [I] .ClickMe,新{@class =TEXT-危险})
< / DIV>
< / DIV>
}
标记:
< DIV CLASS =表单组>
<标签=ViewModels_0__ClickMe> ClickMe< /标签>
< DIV CLASS =COL-MD-10>
<输入名称=的ViewModels [0] .ClickMe级=的形式控制复选框ID =ViewModels_0__ClickMe类型=复选框检查=选中价值=真实数据-VAL -required =该ClickMe字段是必需的。数据-VAL =真正的><输入名称=的ViewModels [0] .ClickMe类型=隐藏值=假>
<跨度类=现场验证,有效文本危险数据valmsg替换=真正的数据valmsg换=的ViewModels [0] .ClickMe>< / SPAN>
< / DIV>
< / DIV>
所以,似乎为
属性是空只有当模型是对象的列表。
这是一个已知的问题?或者,也许我失去了一些东西?
此行为与HTML-4规格符合该框架的结果。在HTML-4
ID和名称标记必须以字母开头([A-ZA-Z]),并可以跟任何字母数字,数字([0-9]),连字符( - ),下划线(_),冒号(:)和句点(。)
。 块引用>
当你的模型是一个集合,并使用
@ Html.EditorFor(M = GT; M [] .SomeProperty)
生成表单控件,该方法生成<基于属性的名称code>名称和ID
属性。在这种情况下,集合中的第一个项目的名称
属性将NAME =[0] .SomeProperty
但要避免使用jQuery选择冲突的方法替换
。
,[
和]
以下划线字符_
生成ID
属性,这将导致
<当pre>ID =_ 0__SomeProperty
但根据,因为这是无效的到HTML-4规格,助手不输出它的HTML。
同样使用时
@ Html.LabelFor()适用
(因为相关的表单控件不会有一个ID
属性的值为
属性是不是在HTML输出。
请注意,在HTML-5,
ID
属性将是有效的,所以希望这种行为将在未来被删除。
您第二个例子工程,因为
ID =ViewModels_0__ClickMe
开始与一个字母,因此是有效的。
附注:您可以通过生成自己的
ID解决第一个问题
属性,例如:@ Html.LabelFor(型号= GT;模型[I] .ClickMe,新{=为的String.Format(项{0},I)})
@ Html.EditorFor(型号=> model.ViewModels [I] .ClickMe,新{ htmlAttributes = {新@class =表格控,ID =的String.Format(项{0},I)}})
If the model is a list of objects then
@Html.LabelFor model => model[i].member)
creates an emptyfor
attribute. The DisplayName works properly, model binding also works just fine. The only thing that does not work is thefor
attribute.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.
What am I missing?
Model:
public class ViewModel { public bool ClickMe { get; set; } }
Controller:
public ActionResult LabelForViewModel() { List<ViewModel> model = new List<ViewModel>() { new ViewModel() { ClickMe = true} }; return View(model); }
View:
@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> }
Markup:
<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>
Please notice that the for field is empty and the input has no id field (that one is used in the "for" field).
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; } }
View:
@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> }
Markup:
<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>
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?
解决方案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 generatesname
andid
attributes based on the name of the property. In this case thename
attribute for the first item in the collection will bename="[0].SomeProperty"
but to avoid clashes with jQuery selectors, the method replaces
.
,[
, and]
characters with an underscore_
when generating theid
attribute which would result inid="_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 anid
attribute, the value of thefor
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) } })
这篇关于剃刀:如果模型列表与LT;>然后@ Html.LabelFor创建emtpy"为"领域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!