如何使用动态模型创建动态表

Posted

技术标签:

【中文标题】如何使用动态模型创建动态表【英文标题】:How to use a dynamic model to create a dynamic table 【发布时间】:2015-06-22 22:46:21 【问题描述】:

我想做一个表,所以我可以加载一个类,然后表会自动生成。

这是我正在寻找的,但我不知道如何实现这一点:

@model dynamic
<table>
<thead>
    <tr>
    @foreach(var record in model.results)
    
        <th>@html.labelfor(item.indexof(...))</th>
    

    </tr>
</thead>
@if (Model.Result.Count() > 0)

    <tbody>
        @for(int i = 0; i < Model.Result.Count(); i++)
        
            <tr>
                @foreach (var item in Model.Result)
                  
                    <td>@item.indexOf(...)</td>
                
            </tr>
        
    </tbody>

else

    <p class="errordata">No data found...</p>

这是我的 ViewModel:

public class issueModel

    public int Id  get; set; 
    public string Name  get; set; 
    public string Color  get; set; 
    public string FontColor  get; set; 
    public int Count  get; set; 
    public string Description  get; set; 
    public string Abbreviation  get; set; 
    public string icon  get; set; 
    public List<dynamic> Result  get; set; 

在“列表结果”中可能会有所不同,这是一个可能在结果中的示例类:

public partial class someClass

    [Display(Name = "PID_1")]
    public int? someProp_1 get; set; 

    [Display(Name = "PID_2")]
    public int? someProp_2 get; set; 

    [StringLength(255)]
    public string PermName1  get; set; 

    [StringLength(255)]
    public string PermName2  get; set; 

    public string description get; set; 

    public int? Prioriteit  get; set; 

    [StringLength(50)]
    public string Login  get; set; 

    public int id get; set; 

我尝试在动态项目上使用 .indexOf,但这不起作用。以某种方式做到这一点吗?还是我必须用单独的表格制作单独的视图?

【问题讨论】:

【参考方案1】:

对于这种情况,您需要反射。您应该构建一个新的 Html Helper。该助手遍历模型的所有公共属性,并使用该信息创建一个表,然后您只需要在视图中调用助手:

助手类:

namespace System.Web.Mvc

    public static class TableHelperExtensions
    
        public static string BuildTr(object _obj)
        
            var properties = _obj.GetType().GetProperties();
            var tr = "<tr>";

            foreach(var property in properties) 
                tr += String.Format("<td>0</td>", property.GetValue(_obj));
            

            tr += "</tr>";

            return (tr);
        

        public static string BuildTrHeader(object _obj)
        
            var properties = _obj.GetType().GetProperties();
            var tr = "<tr>";

            foreach (var property in properties)
            
                tr += String.Format("<th>0</th>", property.Name);
            

            tr += "</tr>";

            return (tr);
        

        public static HtmlString BuildTable(this HtmlHelper helper, object _obj)
        
            if(!IsCollection(_obj.GetType())) 
                throw new InvalidOperationException("BuildTable helper can be called only on collection object");
            

            var tableStart = String.Format(@"<table>
                            <thead>
                                0
                            </thead>
                            <tbody>", BuildTrHeader((_obj as IEnumerable<object>).ElementAt(0)));

            var tableBody = String.Empty;

            var coll = _obj as IEnumerable<object>;

            foreach(var _ in coll)
                tableBody += BuildTr(_);
            

            var tableEnd = @"
                            </tbody>
                        </table>";;

            return new HtmlString(tableStart + tableBody + tableEnd);
        

        static bool IsCollection(Type type)
        
            return type.GetInterface(typeof(IEnumerable<>).FullName) != null;
         
    

示例视图:

@
    Layout = null;

    var objs = new List<object>();

    objs.Add(new  a = "Hello", b = "World" );
    objs.Add(new  a = "World", b = "Hello" );


<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Test</title>
</head>
<body>
    @Html.BuildTable(objs)
</body>
</html>

【讨论】:

【参考方案2】:

看看ModelMetadata。 还要看看 ModelMetadataProvider,甚至是 CustomMetadataProvider。

我通常使用这些来呈现完整的编辑器对话框。

ModelMetadata metadata = (ModelMetadata)ViewData.ModelMetadata;
ModelMetadata[] properties = metadata.Properties.Where(pm => pm.ShowForEdit && (pm.IsReadOnly || !ViewData.TemplateInfo.Visited(pm))).ToArray();
foreach (TemplateMetadata prop in properties)

    if (!prop.HideSurroundingHtml)
    
        @Html.Label(prop.PropertyName, prop.DisplayName + ((prop.ModelType != typeof(bool) && prop.IsRequired) ? " *" : ""))
    

【讨论】:

以上是关于如何使用动态模型创建动态表的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Core Data 模型中动态创建新实体(表)?

ASP.NET MVC 如何从嵌套对象的视图模型集合中动态创建表结构

如何将 json 数据与 Angular 材质表绑定以创建动态表?

如何使用动态对象类创建 .net 核心 MVC 模型?

如何在 laravel 4.2 中动态更改模型表?

如何使用 Ajax 成功创建动态表