使用视图模型动态绑定 HTML table 失败

Bind HTML table TH dynamically using View Model Failed

我正在尝试使用 Razor 页面上对象类型的视图模型绑定 HTML table。代码如下:

index.cshtml.cs

[BindProperty]
public List<object> TableData { get; set; }

public class Cainfo
{
   public string Ca_id { get; set; }
   public object Nca { get; set; }
}

public async Task<IActionResult> OnGetAsync()
{
   List<object> tablerows = GetTableRows(tabledata);
   TableData = tablerows;
}

public List<object> GetTableRows(GetTableRowsResponse getTableRowsResponse)
{
       List<object> tableRows = new List<object>();
            
       var tables = getTableRowsResponse.rows;
       foreach (var table in tables)
       {
             var tab = JsonConvert.SerializeObject(table);
             var row = JsonConvert.DeserializeObject<Cainfo>(tab);
             tableRows.Add(row);
       }
       return tableRows;
}

index.cshtml

<table class="resultTable">
   <thead class="grid-header">                                                 
      <tr>                             
        @foreach (var property in @Model.TableData.GetType().GetGenericArguments()[0].GetProperties())
        {
          <th class="col-lg-1">@property.Name</th>
        }
       </tr>
    </thead>
    <tbody class="grid-body">
       @if (@Model.TableData != null)
       {
           @if ((@Model.TableData.Count != 0))
           {
              @foreach (var row in Model.TableData)
              {
                 <tr>
                  @foreach (var property in @row.GetType().GetProperties())
                  {
                     <td class="col-lg-1">@property.GetValue(@row)</td>
                  }
                 </tr>
              }
           }
       }                                
     </tbody>
</table>

var tables = getTableRowsResponse.rows; return JSON 数据。问题是 table <th> 没有绑定。 @Model.TableData.GetType().GetGenericArguments()[0].GetProperties() 变空了。 <td> 正按预期进行绑定。也许我在某个地方犯了一个错误,我是 asp .net 核心的新手。现在,我使用的是模型Cainfo,但以后,我需要根据数据设置不同的模型并绑定相同的table。这就是为什么我将 View Model 类型指定为 Object。请帮忙。

当您可以为视图设计通用模型时,我不会像这样使用反射。这就是让事情变得更简单的设计艺术。但是,这里假设您无论如何都想坚持使用该解决方案,我将展示它的错误所在、如何修复它以及它的局限性。

首先这个 Model.TableData.GetType().GetGenericArguments()[0] 将 return TypeobjectType 当然不包含任何属性。这就是为什么你没有得到 <th> 渲染。通用参数类型完全反映了为 Model.TableData 声明的内容,即 List<object>.

现在修复它,假设List<object>中的所有项目都是同一类型,你可以得到第一个项目的Type,像这样:

@foreach (var property in @Model.TableData?.FirstOrDefault()
                                          ?.GetType()?.GetProperties() 
                                          ?? Enumerable.Empty<PropertyInfo>())
{
   <th class="col-lg-1">@property.Name</th>
}

如果 Model.TableData 不包含任何项目,则有一个限制。不会呈现 <th>。如果那是 acceptable(而不是用 headers 渲染一个空的 table,你将什么都不渲染或只渲染一些消息)那么就那样做。否则,您需要通过模型为 element/row 的 Type 提供 Type,例如通过像 Model.RowType 这样的 属性。然后你可以用那个代替这个:

 Model.TableData?.FirstOrDefault()?.GetType()

其余代码完全相同。