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

ASP.NET Repeater按钮点击事件中DataItem为空的问题求助

问题:Repeater按钮点击时Item.DataItem为空,无法获取行数据跳转编辑页

我要实现Repeater中按钮点击时获取对应行数据,拼接URL跳转到编辑页,但点击按钮时item.DataItem为空。Repeater初始绑定正常,能正确显示数据;点击按钮会触发Page_Load,尝试过在点击事件中重新绑定Repeater,问题仍未解决。

原因分析

在ASP.NET回发机制中,Item.DataItem仅在数据绑定阶段(即DataBind()执行时)有效。回发时(比如点击按钮),Repeater不会自动重新绑定数据,因此Item.DataItem会是空值——哪怕手动在点击事件里重新绑定,此时也已经错过数据绑定时机,无法通过DataItem获取数据。

解决方案

方法1:通过CommandArgument传递主键,重新查询数据(推荐)

只需要把主键DealerContactId作为按钮的CommandArgument,点击时用主键重新查询该行完整数据,再拼接URL。这种方式简洁,还能避免在前端暴露大量数据。

修改前端按钮代码:

<asp:Button ID="btnEdit" runat="server" Text="Edit" OnClick="btnEdit_Click" CommandArgument='<%# Eval("DealerContactId") %>' />

修改后台按钮点击事件:

protected void btnEdit_Click(object sender, EventArgs e)
{
    Button btnEdit = (Button)sender;
    int dealerContactId = Convert.ToInt32(btnEdit.CommandArgument);
    
    // 用主键重新查询该行数据,复用现有GetDealerContactInfo方法,或单独实现按ID查询的逻辑
    var contact = GetDealerContactInfo().Cast<DataRowView>().FirstOrDefault(r => Convert.ToInt32(r["DealerContactId"]) == dealerContactId);
    
    if (contact != null)
    {
        ContactTitles title = (ContactTitles)Enum.Parse(typeof(ContactTitles), contact["NameTitleId"].ToString());
        bool isChecked = Convert.ToBoolean(contact["DecisionMaker"]);
        ContactPositions position = (ContactPositions)Enum.Parse(typeof(ContactPositions), contact["DealerContactPositionId"].ToString());
        string forename = contact["Forename"].ToString();
        string surname = contact["Surname"].ToString();
        string phone = contact["PhoneNumber"].ToString();
        string direct = contact["DirectDialNumber"].ToString();
        string fax = contact["FaxNumber"].ToString();
        string mobile = contact["MobileNumber"].ToString();
        string email = contact["EmailAddress"].ToString();
        string secondEmail = contact["SecondaryEmail"].ToString();

        string editUrl = $"EditPage.aspx?dealerContactId={dealerContactId}&title={(int)title}&isChecked={isChecked}&position={(int)position}&forename={Uri.EscapeDataString(forename)}&surname={Uri.EscapeDataString(surname)}&phone={Uri.EscapeDataString(phone)}&direct={Uri.EscapeDataString(direct)}&fax={Uri.EscapeDataString(fax)}&mobile={Uri.EscapeDataString(mobile)}&email={Uri.EscapeDataString(email)}&secondEmail={Uri.EscapeDataString(secondEmail)}";

        Response.Redirect(editUrl);
    }
}

方法2:把数据存储在前端隐藏控件中

如果不想重新查询数据库,可以把需要的字段放在前端隐藏控件里,点击时从RepeaterItem中找到这些控件获取值。

修改Repeater的ItemTemplate(将需要的字段改为服务器端隐藏Label):

<ItemTemplate>
    <tr>
        <td> <asp:Button ID="btnEdit" runat="server" Text="Edit" OnClick="btnEdit_Click" CommandArgument='<%# Container.ItemIndex %>' /></td>
        <td style="display:none;"><asp:Label ID="lblDealerContactId" runat="server" Text='<%# Eval("DealerContactId") %>'></asp:Label></td>
        <td><%# GetTitleText((byte)Eval("NameTitleId")) %></td>
        <td><%# Eval("Forename") %> <%# Eval("Surname") %></td>
        <td><asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Eval("DecisionMaker") %>' Enabled="false" /></td>
        <td><%# GetPositionText((byte)Eval("DealerContactPositionId")) %></td>
        <td style="display:none;"><asp:Label ID="lblForename" runat="server" Text='<%# Eval("Forename") %>'></asp:Label></td>
        <td style="display:none;"><asp:Label ID="lblSurname" runat="server" Text='<%# Eval("Surname") %>'></asp:Label></td>
        <td style="display:none;"><asp:Label ID="lblPhone" runat="server" Text='<%# Eval("PhoneNumber") %>'></asp:Label></td>
        <td style="display:none;"><asp:Label ID="lblDirect" runat="server" Text='<%# Eval("DirectDialNumber") %>'></asp:Label></td>
        <td style="display:none;"><asp:Label ID="lblFax" runat="server" Text='<%# Eval("FaxNumber") %>'></asp:Label></td>
        <td style="display:none;"><asp:Label ID="lblMobile" runat="server" Text='<%# Eval("MobileNumber") %>'></asp:Label></td>
        <td style="display:none;"><asp:Label ID="lblEmail" runat="server" Text='<%# Eval("EmailAddress") %>'></asp:Label></td>
        <td style="display:none;"><asp:Label ID="lblSecondEmail" runat="server" Text='<%# Eval("SecondaryEmail") %>'></asp:Label></td>
        <td style="display:none;"><asp:Label ID="lblNameTitleId" runat="server" Text='<%# Eval("NameTitleId") %>'></asp:Label></td>
        <td style="display:none;"><asp:Label ID="lblPositionId" runat="server" Text='<%# Eval("DealerContactPositionId") %>'></asp:Label></td>
    </tr>
</ItemTemplate>

修改后台按钮点击事件:

protected void btnEdit_Click(object sender, EventArgs e)
{
    Button btnEdit = (Button)sender;
    RepeaterItem item = (RepeaterItem)btnEdit.NamingContainer;
    
    try
    {
        int dealerContactId = Convert.ToInt32(((Label)item.FindControl("lblDealerContactId")).Text);
        ContactTitles title = (ContactTitles)Convert.ToByte(((Label)item.FindControl("lblNameTitleId")).Text);
        bool isChecked = ((CheckBox)item.FindControl("CheckBox1")).Checked;
        ContactPositions position = (ContactPositions)Convert.ToByte(((Label)item.FindControl("lblPositionId")).Text);
        string forename = ((Label)item.FindControl("lblForename")).Text;
        string surname = ((Label)item.FindControl("lblSurname")).Text;
        string phone = ((Label)item.FindControl("lblPhone")).Text;
        string direct = ((Label)item.FindControl("lblDirect")).Text;
        string fax = ((Label)item.FindControl("lblFax")).Text;
        string mobile = ((Label)item.FindControl("lblMobile")).Text;
        string email = ((Label)item.FindControl("lblEmail")).Text;
        string secondEmail = ((Label)item.FindControl("lblSecondEmail")).Text;

        string editUrl = $"EditPage.aspx?dealerContactId={dealerContactId}&title={(int)title}&isChecked={isChecked}&position={(int)position}&forename={Uri.EscapeDataString(forename)}&surname={Uri.EscapeDataString(surname)}&phone={Uri.EscapeDataString(phone)}&direct={Uri.EscapeDataString(direct)}&fax={Uri.EscapeDataString(fax)}&mobile={Uri.EscapeDataString(mobile)}&email={Uri.EscapeDataString(email)}&secondEmail={Uri.EscapeDataString(secondEmail)}";

        Response.Redirect(editUrl);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

注意事项

  • 方法1更推荐,无需在前端暴露过多数据,避免数据被篡改的风险,通过主键查询保证数据准确性。
  • 方法2适合简单场景,但敏感数据不要放在前端隐藏控件中,防止被恶意获取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:37:12