You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用嵌套ASP Repeater绑定复杂对象实现动态表格的方案咨询

实现方案

核心思路

首先需要把API返回的扁平键值对结构,先转换为按联系人分组的结构化数据,再绑定到Repeater渲染即可。动态列场景总共只需要3层Repeater,固定列场景仅需1层Repeater即可实现。

前置准备:数据结构转换

首先定义API返回的单个字段项实体:

public class ApiContactField
{
    public string FieldName { get; set; }
    public string FieldValue { get; set; }
}

第一步先对返回的字段列表做结构化处理:

// 页面级全局变量,存储去重后的列名,顺序和API返回一致
private List<string> _columnNames;

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack)
    {
        // 假设apiResult是接口返回的List<ApiContactField>
        List<ApiContactField> apiResult = GetApiContactsData();
        
        // 1. 提取去重列名
        _columnNames = apiResult.Select(x => x.FieldName).Distinct().ToList();
        
        // 2. 按列数拆分扁平列表,组装为联系人分组数据
        List<Dictionary<string, string>> structuredContacts = new List<Dictionary<string, string>>();
        int columnCount = _columnNames.Count;
        for(int i = 0; i < apiResult.Count; i += columnCount)
        {
            Dictionary<string, string> contact = new Dictionary<string, string>();
            for(int j = 0; j < columnCount; j++)
            {
                contact[_columnNames[j]] = apiResult[i + j].FieldValue;
            }
            structuredContacts.Add(contact);
        }
        
        // 绑定数据到Repeater
        rptTableHeader.DataSource = _columnNames;
        rptTableHeader.DataBind();
        rptContactRows.DataSource = structuredContacts;
        rptContactRows.DataBind();
    }
}

场景1:动态列适配(字段数量不固定)

前端代码

<table style="border-collapse: collapse;" border="1" cellpadding="6">
    <thead>
        <tr>
            <!-- 表头Repeater:渲染所有列名 -->
            <asp:Repeater ID="rptTableHeader" runat="server">
                <ItemTemplate>
                    <th><%# Container.DataItem.ToString() %></th>
                </ItemTemplate>
            </asp:Repeater>
        </tr>
    </thead>
    <tbody>
        <!-- 数据行Repeater:渲染每个联系人的行 -->
        <asp:Repeater ID="rptContactRows" runat="server" OnItemDataBound="rptContactRows_ItemDataBound">
            <ItemTemplate>
                <tr>
                    <!-- 行内字段Repeater:渲染当前行的每个单元格值 -->
                    <asp:Repeater ID="rptCellValues" runat="server" OnItemDataBound="rptCellValues_ItemDataBound">
                        <ItemTemplate>
                            <td>
                                <asp:Literal ID="ltCellValue" runat="server"/>
                            </td>
                        </ItemTemplate>
                    </asp:Repeater>
                </tr>
            </ItemTemplate>
        </asp:Repeater>
    </tbody>
</table>

绑定事件代码

protected void rptContactRows_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        // 获取当前行的联系人数据
        var currentContact = (Dictionary<string, string>)e.Item.DataItem;
        // 找到当前行的单元格Repeater
        var rptCellValues = (Repeater)e.Item.FindControl("rptCellValues");
        // 绑定列名作为数据源,按顺序渲染单元格
        rptCellValues.DataSource = _columnNames;
        rptCellValues.DataBind();
    }
}

protected void rptCellValues_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        // 获取当前列名
        string currentCol = e.Item.DataItem.ToString();
        // 获取父级行的联系人数据
        var parentRow = (RepeaterItem)e.Item.NamingContainer.NamingContainer;
        var currentContact = (Dictionary<string, string>)parentRow.DataItem;
        // 赋值单元格内容
        var ltCellValue = (Literal)e.Item.FindControl("ltCellValue");
        ltCellValue.Text = currentContact[currentCol];
    }
}

场景2:固定列适配(确定只有姓名、电话、地址3个字段)

如果字段固定无需动态适配,可以简化为1层Repeater,无需写绑定事件:

前端代码

<table style="border-collapse: collapse;" border="1" cellpadding="6">
    <thead>
        <tr>
            <th>Name</th>
            <th>Phone Number</th>
            <th>Address</th>
        </tr>
    </thead>
    <tbody>
        <asp:Repeater ID="rptContacts" runat="server">
            <ItemTemplate>
                <tr>
                    <td><%# Eval("Name") %></td>
                    <td><%# Eval("PhoneNumber") %></td>
                    <td><%# Eval("Address") %></td>
                </tr>
            </ItemTemplate>
        </asp:Repeater>
    </tbody>
</table>

数据绑定代码

可以先定义强类型联系人实体,预处理时直接转成实体列表绑定即可:

public class Contact
{
    public string Name { get; set; }
    public string PhoneNumber { get; set; }
    public string Address { get; set; }
}

// Page_Load中的预处理逻辑调整为:
List<Contact> structuredContacts = new List<Contact>();
int columnCount = _columnNames.Count;
for(int i = 0; i < apiResult.Count; i += columnCount)
{
    Contact contact = new Contact
    {
        Name = apiResult[i].FieldValue,
        PhoneNumber = apiResult[i+1].FieldValue,
        Address = apiResult[i+2].FieldValue
    };
    structuredContacts.Add(contact);
}
rptContacts.DataSource = structuredContacts;
rptContacts.DataBind();

内容的提问来源于stack exchange,提问作者obautista

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:36:07