ASP.net MVC - Display Template for a collection

前端 未结 4 1268
自闭症患者
自闭症患者 2020-12-01 04:19

I have the following model in MVC:

public class ParentModel
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }

    public         


        
4条回答
  •  北荒
    北荒 (楼主)
    2020-12-01 04:53

    This is in reply to Maslow's comment. This is my first ever contribution to SO, so I don't have enough reputation to comment - hence the reply as an answer.

    You can set the 'TemplateHint' property in the ModelMetadataProvider. This would auto hookup any IEnumerable to a template you specify. I just tried it in my project. Code below -

    protected override CachedDataAnnotationsModelMetadata CreateMetadataFromPrototype(CachedDataAnnotationsModelMetadata prototype, Func modelAccessor)
        {
            var metaData = base.CreateMetadataFromPrototype(prototype, modelAccessor);
            var type = metaData.ModelType;
    
            if (type.IsEnum)
            {
                metaData.TemplateHint = "Enum";
            }
            else if (type.IsAssignableFrom(typeof(IEnumerable)))
            {
                metaData.TemplateHint = "Collection";
            }
    
            return metaData;
        }
    
    
    

    You basically override the 'CreateMetadataFromPrototype' method of the 'CachedDataAnnotationsModelMetadataProvider' and register your derived type as the preferred ModelMetadataProvider.

    In your template, you cannot directly access the ModelMetadata of the elements in your collection. I used the following code to access the ModelMetadata for the elements in my collection -

    @model IEnumerable
    @{ 
    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 view, I simply call @Html.DisplayForModel() and the template gets loaded. There is no need to specify 'UIHint' on models.

    I hope this was of some value.

    提交回复
    热议问题