我有一个具有 IEnumerable 属性的模型(要遵循警告伪代码)
public class PersonModel {
public string Name { get; set; }
public IEnumerable<AddressModel> Addresses { get; set; }
}
public class AddressModel {
public string Name { get; set; }
}
我想在同一个视图中显示地址子对象
个人.cshtml
@model PersonModel
<form>
<h2>Person</h2>
@Html.EditorFor(m=>m.Name)
<ul>@Html.EditorFor(m=>m.Addresses)</ul>
</form>
编辑器模板/地址模型
@model AddressModel
<li>@Html.TextboxFor(m=>m.Name)</li>
太棒了,一切正常
但是,作为一个 git,我现在想开始使用模板布局以标准类型的方式和东西包装我的所有属性
因此,我创建了一个 string.cshtml 和一个 list.cshtml 来执行此操作,并使用 _Control.cshtml 进行布局
EditorTemplates/_Control.cshtml
<div>
@Html.Label(string.Empty)
<div class="input">
@RenderBody()
@Html.ValidationMessage(string.Empty)
</div>
</div>
EditorTemplates/string.cshtml
@model string
@{
Layout = "_Control.cshtml";
}
@Html.TextBox(string.Empty, Model)
(到目前为止是的!但是等等..哦不..)
这就是麻烦
<ul>@Html.EditorFor(m=>m.Addresses)</ul>
从主视图(见上文)变为
@Html.EditorFor(m=>m.Addresses, "List")
EditorTemplates/list.cshtml
@model IEnumerable<object>
@{
Layout = "_Control.cshtml";
}
<ul>
@foreach(var item in Model){
@Html.EditorFor(m => item)
}
</ul>
这会错误地呈现 id 和名称,例如 Addresses_item_Name,其中不包含 Id,因此使用 for 循环添加 id
@for (var i = 0; i < Model.Count();i++ ) {
@Html.EditorFor(m => Model.ElementAt(i))
}
这会爆炸,因为 MVC 表达式助手除了数组之外不允许任何内容,但 Addresses 必须是 IEnumerable<> 因为 EF4.1 不支持子查询中的 .ToArray ,即。
var model = (from p in DataContext.People
where p.Id = 1
select new PersonModel {
Name = p.Name,
Addresses = (from a in p.Addresses
select new AddressModel {
Name = a.Name
}).ToArray() // **NOT SUPPORTED**
}).FirstOrDefault();
有没有人反对这个?有标准的方法吗?
这行得通,但是对吗?
EditorTemplates/list.cshtml
@model IEnumerable<object>
@{
Layout = "_Control.cshtml";
var prefix = ViewData.TemplateInfo.HtmlFieldPrefix;
}
<ul>
@for (var i = 0; i < Model.Count();i++ ) {
var item = Model.ElementAt(i);
ViewData.TemplateInfo.HtmlFieldPrefix = string.Format("{0}[{1}]",prefix, i);
@Html.EditorFor(m => item, null, string.Empty)
}
</ul>
所需的结构是
<form>
<control>
Person Name Control Elements
<control>
<control>
Address List Control Elements
<control>
</form>