这是对马斯洛评论的回应。这是我对 SO 的第一次贡献,因此我没有足够的声誉来发表评论 - 因此将回复作为答案。
您可以在 ModelMetadataProvider 中设置“TemplateHint”属性。这会将任何 IEnumerable 自动连接到您指定的模板。我刚刚在我的项目中尝试过。下面的代码 -
protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
{
var metaData = base.CreateMetadataFromPrototype(prototype, modelAccessor);
var type = metaData.ModelType;
if (type.IsEnum)
{
metaData.TemplateHint = "Enum";
}
else if (type.IsAssignableFrom(typeof(IEnumerable<object>)))
{
metaData.TemplateHint = "Collection";
}
return metaData;
}
您基本上覆盖了“CachedDataAnnotationsModelMetadataProvider”的“CreateMetadataFromPrototype”方法,并将您的派生类型注册为首选的 ModelMetadataProvider。
在您的模板中,您不能直接访问集合中元素的 ModelMetadata。我使用以下代码访问集合中元素的 ModelMetadata -
@model IEnumerable<object>
@{
var modelType = Model.GetType().GenericTypeArguments[0];
var modelMetaData = ModelMetadataProviders.Current.GetMetadataForType(null, modelType.UnderlyingSystemType);
var propertiesToShow = modelMetaData.Properties.Where(p => p.ShowForDisplay);
var propertiesOfModel = modelType.GetProperties();
var tableData = propertiesOfModel.Zip(propertiesToShow, (columnName, columnValue) => new { columnName.Name, columnValue.PropertyName });
}
在我看来,我只需调用 @Html.DisplayForModel() 并加载模板。无需在模型上指定“UIHint”。
我希望这有一些价值。