This is a response to Maslow's comment. This is my first contribution to SO, so I do not have enough reputation to comment - hence the answer as an answer.
You can set the "TemplateHint" property in ModelMetadataProvider. This will automatically connect any IEnumerable to the specified template. I just tried this in my project. The code below is
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; }
You basically override the CreateMetadataFromPrototype method for 'CachedDataAnnotationsModelMetadataProvider' and register your derived type as the preferred ModelMetadataProvider.
In a template, you cannot directly access ModelMetadata from the elements of your collection. I used the following code to access ModelMetadata for items in my collection -
@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 }); }
In my opinion, I just call @ Html.DisplayForModel () and the template loads. There is no need to indicate "UIHint" on models.
I hope this made some difference.
swazza85 Aug 03 '13 at 18:05 2013-08-03 18:05
source share