@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)
}
}
But please note that if you don't rely on the established conventions for resolving templates for complex collection types (a.k.a ~/Views/Shared/EditorTemplates/NameOfTheTypeOfCollectionElements.cshtml
) and have used an UIHint
on your collection property:
[UIHint("FooBar")]
public IEnumerable<FooViewModel> Foos { get; set; }
then the ~/Views/Shared/EditorTemplates/FooBar.cshtml
editor template must be strongly typed to IEnumerable<FooViewModel>
and not FooViewModel
. So be careful, if this is your case, it's up to you to loop inside this custom template if you want to get to individual items of the collection. It will no longer be ASP.NET MVC that will automatically loop for you and invoke the editor template for each element.
UPDATE:
Still can't repro your issue.
Custom attribute:
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;
}
}
Model:
public class MyViewModel
{
[ACustom("Something")]
public IEnumerable<int> Foos { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Foos = Enumerable.Range(1, 5)
};
return View(model);
}
}
View (~/Views/Home/Index.cshtml
):
@model MyViewModel
@using (Html.BeginForm())
{
@Html.EditorForModel()
}
Editor template for the object type (~/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)
}
}
Custom editor template (~/Views/Shared/EditorTemplates/Something.cshtml
):
@model IEnumerable<int>
<h3>
@ViewData.ModelMetadata.AdditionalValues["foo"]
</h3>
@foreach (var item in Model)
{
<div>
@item
</div>
}
Result:

So as you can see the additional metadata we added is shown in the template.