[Validator(typeof(ProdutoCategoriaValidator))]
public class ProdutoCategoriaViewModel
{
[HiddenInput(DisplayValue = false)]
public Guid ID { get; set; }
public IEnumerable<SelectListItem> Tipos { get; set; } // <<<<------- Is not showing in my view
[AdditionalMetadata("data-bind", "event: { change: function(data) { Link(data.Nome()); }}")]
public string Nome { get; set; }
[DataType(DataType.Url)]
[AdditionalMetadata("Prefixo", "Produtos/{tipo-de-produto}#")]
public string Link { get; set; }
public int? Ordem { get; set; }
public ProdutoCategoriaViewModel()
{
ID = Guid.NewGuid();
}
}
@model ProdutoCategoriaViewModel
@using (Html.BeginForm(null, null, FormMethod.Post, new { id="form-produtocategoria", data_bind = "submit: salvar" }))
{
@Html.AntiForgeryToken()
<legend>@Html.MvcSiteMap().SiteMapTitle()</legend>
<fieldset>
@Html.ValidationSummary(false, "Verifique os erros abaixo:")
@Html.EditorForModel()
</fieldset>
<div class="buttons">
@Html.ActionLink("Cancelar", "Index")
<input type="submit" value="SALVAR" />
</div>
}
@model IEnumerable<SelectListItem>
@Html.DropDownListFor(m => m, Model)
<p>Test</p>
完整图片:http://i.imgur.com/I7HxA.png
我做错了什么?
答案 0 :(得分:3)
默认情况下,当您使用Html.EditorForModel
时,请不要期望将其递归到复杂属性,例如类型为Tipos
的{{1}}属性。布拉德威尔逊在他的blog post中解释了这一点(更具体地说,在帖子结尾处阅读了浅水潜水与深潜部分)。如果您希望这样做,您将需要为Object类型编写自定义编辑器模板。
另一种可能性是指定模板名称:
IEnumerable<SelectListItem>
另外请记住,@Html.EditorFor(x => x.Tipos, "SelectListItem")
的编辑器模板是错误的,因为您将DropDownListFor绑定到模型作为第一个参数。不要忘记这个帮助器的第一个参数必须是一个标量属性,用于保存选定的值。您需要在视图模型上使用字符串或整数属性。第二个参数代表集合。
关于编辑器模板的另一个重要方面是,当您拥有类型为SelectListItem
的属性和名为IEnumerable<T>
的编辑器模板时,此编辑器模板必须强类型化为T.cshtml
类,而不是与T
模板一样IEnumerable<T>
。如果您使用UIHint或将模板名称指定为EditorFor帮助程序的第二个参数,则不适用。在这种情况下,模板将被输入到集合中。
回顾一下,您可以实现自定义对象编辑器模板,因为Brad Wilson建议将递归到复杂属性,或者您可以修改SelectListItem.cshtml
视图以指定EditorFor每个元素。
答案 1 :(得分:1)
@foreach
循环呈现看起来正确的内容,但生成的标记对于每一行的控件都具有相同的ID。它也不会使用模型实例发回可枚举的集合。
有两种方法可以使这项工作成为集合中每个项目的唯一ID,以便集合在回发中保持水分:
<强> 1。使用默认编辑器模板而不是命名模板
// editor name parameter must be omitted; default editor template's model type
// should be a single instance of the child object, not an IEnumerable. This
// convention looks wrong, but it fully works:
@Html.EditorFor(parentObject => parentObject.Items)
<强> 2。使用@for
循环,而不是@foreach
:
@for (int i = 0; i < parentObject.Items.Count ; i++) {
// the model binder uses the indexer to disambiguate the collection items' controls:
@Html.EditorFor(c => Model.Items[i], "MyEditorTemplate")
}
但这不起作用:
// this will error out; the model type will not match the view's at runtime:
@Html.EditorFor(parentObject => parentObject.Items, "MyEditorTemplate")
这也不会:
@foreach(var item in parentObject.Items) {
// this will render, but won't post the collection items back with the model instance:
@Html.EditorFor(c => item, "MyEditorTemplate")
}
要详细解答原因,请查看以下问题:MVC can't override EditorTemplate name when used in EditorFor for child object。