我知道在使用EditorForModel时通常不会渲染复杂类型,但我使用的是不执行检查的自定义对象模板,并为包括复杂类型在内的每个属性调用Html.Editor。
不幸的是,虽然我可以在对象模板中看到属性的正确TemplateHint值,但是编辑器调用似乎没有使用它,而是使用了内置的集合模板。
我的对象模板基本上是这样的:
@foreach (var property in ViewData.ModelMetadata.Properties.Where(x => x.ShowForEdit))
{
@Html.Editor(property.PropertyName)
}
如果我通过将名称传递给编辑器调用来强制使用模板,则模板中的ModelMetadata为空。
这是一个错误/是否有任何变通方法?
更多信息:
所以我的视图模型包含以下内容:
[ACustomAttribute("Something")]
public IEnumerable<int> SelectedOptions { get; set; }
该属性实现IMetadataAware并将一些内容添加到ModelMetadata的AdditionalValues集合以及设置TemplateHint。我可以从对象模板中读取这些数据,但不能从我的自定义模板中读取。
答案 0 :(得分:2)
@foreach (var property in ViewData.ModelMetadata.Properties.Where(x => x.ShowForEdit))
{
if (!string.IsNullOrEmpty(property.TemplateHint))
{
@Html.Editor(property.PropertyName, property.TemplateHint)
}
else
{
@Html.Editor(property.PropertyName)
}
}
但请注意,如果您不依赖已建立的约定来解析复杂集合类型的模板(a.k.a ~/Views/Shared/EditorTemplates/NameOfTheTypeOfCollectionElements.cshtml
)并在您的集合属性上使用UIHint
:
[UIHint("FooBar")]
public IEnumerable<FooViewModel> Foos { get; set; }
然后~/Views/Shared/EditorTemplates/FooBar.cshtml
编辑器模板必须强烈输入IEnumerable<FooViewModel>
而不是FooViewModel
。所以要小心,如果这是你的情况,如果你想要获得集合的各个项目,你可以在这个自定义模板中循环。它将不再是ASP.NET MVC,它将自动为您循环并为每个元素调用编辑器模板。
更新:
仍无法重复你的问题。
自定义属性:
public class ACustomAttribute : Attribute, IMetadataAware
{
private readonly string _templateHint;
public ACustomAttribute(string templateHint)
{
_templateHint = templateHint;
}
public void OnMetadataCreated(ModelMetadata metadata)
{
metadata.AdditionalValues["foo"] = "bar";
metadata.TemplateHint = _templateHint;
}
}
型号:
public class MyViewModel
{
[ACustom("Something")]
public IEnumerable<int> Foos { get; set; }
}
控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Foos = Enumerable.Range(1, 5)
};
return View(model);
}
}
查看(~/Views/Home/Index.cshtml
):
@model MyViewModel
@using (Html.BeginForm())
{
@Html.EditorForModel()
}
对象类型的编辑器模板(~/Views/Shared/EditorTemplates/Object.cshtml
):
@foreach (var property in ViewData.ModelMetadata.Properties.Where(x => x.ShowForEdit))
{
if (!string.IsNullOrEmpty(property.TemplateHint))
{
@Html.Editor(property.PropertyName, property.TemplateHint)
}
else
{
@Html.Editor(property.PropertyName)
}
}
自定义编辑器模板(~/Views/Shared/EditorTemplates/Something.cshtml
):
@model IEnumerable<int>
<h3>
@ViewData.ModelMetadata.AdditionalValues["foo"]
</h3>
@foreach (var item in Model)
{
<div>
@item
</div>
}
结果:
因此,您可以看到我们添加的其他元数据显示在模板中。