我有一个 BookCreateModel,其中包含书籍的平面信息,例如 Title、PublishYear 等以及书籍作者的集合(复杂类型):
public class BookCreateModel
{
public string Title { get; set; }
public int Year { get; set; }
public IList<AuthorEntryModel> Authors { get; set; }
}
public class AuthorEntryModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
在 CreateBook View 中我使用了
EditorFor
helper :@Html.EditorFor(m => m.Authors, "AuthorSelector")
编辑1:
AuthorSelector 模板如下:
<div class="ptr_authors_wrapper">
@for (int i = 0; i < Model.Count; i++)
{
<div class="ptr_author_line" data-line-index="@i">
@Html.TextBoxFor(o => o[i].FirstName)
@Html.TextBoxFor(o => o[i].LastName)
</div>
}
</div>
<script>
...
</script>
AuthorSelector
模板包含一些包装标记,这些标记需要了解每个渲染项的索引,以及一些处理子输入交互并且需要渲染一次的 javascript(在 AuthorSelector
模板内),从而摆脱了 for 循环/或 AuthorSelector模板是不可能的。现在的问题是 EditorFor 的行为有点奇怪,并生成这样的输入名称:
<input id="Authors__0__FirstName" name="Authors.[0].FirstName" type="text" value="" />
<input id="Authors__0__LastName" name="Authors.[0].LastName" type="text" value="" />
如您所见,而不是生成像
Authors[0].FirstName
这样的名称它添加了一个额外的点,使默认模型绑定(bind)器无法解析发布的数据。任何的想法 ?
谢谢 !
最佳答案
我建议您遵守约定,即替换:
@Html.EditorFor(m => m.Authors, "AuthorSelector")
和:
@Html.EditorFor(m => m.Authors)
然后重命名你的
~/Views/Shared/EditorTemplates/AuthorSelector.cshtml
至~/Views/Shared/EditorTemplates/AuthorEntryModel.cshtml
并将其强类型化为单个 AuthorEntryModel
模型并摆脱循环:@model AuthorEntryModel
@Html.TextBoxFor(o => o.FirstName)
@Html.TextBoxFor(o => o.LastName)
ASP.NET MVC 将自动为集合的所有元素呈现编辑器模板并生成正确的名称。
更新:
看到您的更新后,这是我的回复:
在您的主视图中:
<div class="ptr_authors_wrapper">
@Html.EditorFor(m => m.Authors)
</div>
在您的编辑器模板中:
@model AuthorEntryModel
<div class="ptr_author_line">
@Html.TextBoxFor(o => o.FirstName)
@Html.TextBoxFor(o => o.LastName)
</div>
您会注意到模板中没有脚本,这是完全正常的。脚本与标记无关。它们进入单独的 javascript 文件。在这个文件中,您可以使用 jQuery 对您的标记做任何您需要做的事情。它为您提供诸如
.index()
之类的方法这允许您在匹配的选择器中获取元素的索引,这样您就不需要编写任何循环并用 data-line-index
之类的东西污染您的标记属性。
关于asp.net-mvc - 将集合传递给 EditorFor() 时,它会为输入元素生成无效名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11403442/