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

ASP.NET C# GridView调用Rows[index]抛出索引超出范围异常

GridView行选择时索引超出范围问题排查

问题背景

开发用于在GridView控件中展示SQL数据表存储的可用门店信息的用户控件,供用户选择后填充对应文本框。目前已完成GridView全量数据绑定,每行内置的选择按钮可正常触发操作,但存在以下异常:

  • 使用Rows[index]语法获取行对象时,无法将单元格值提取到变量,抛出索引超出范围异常
  • 调试确认获取的索引值完全正确,手动将索引值设为0、1测试仍触发相同错误,表现如同GridView内不存在任何数据行
  • 实现逻辑:使用ButtonField作为选择按钮,触发GridView的OnRowCommand事件执行选择逻辑
  • 已排查常见错误诱因:不存在索引值为负数、未配置DataKeyNames属性的问题,始终无法修复错误

相关实现代码

GridView前端代码

<asp:GridView ID="gvStore" runat="server" AutoGenerateColumns="False" Visible="false" DataKeyNames="Name" OnRowCommand="gvExecSelectSTR_RowCommand">
    <Columns>            
        <asp:BoundField DataField="Name" HeaderText="Name" />            
        <asp:ButtonField ButtonType="Link" Text="Select" CommandName="SelectStore"/> 
    </Columns>
</asp:GridView>

行选择后台事件代码

protected void gvExecSelectSTR_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "SelectStore")
    {
        int index = Convert.ToInt32(e.CommandArgument); // 调试确认此处获取的行索引值正确
        GridViewRow row = gvStore.Rows[index]; // 该行触发索引超出范围错误
        IDStore.Text = row.Cells[0].Text;
    }
}

GridView数据绑定方法代码

private void GridViewStore()
{
    try
    {
        DataTable StoreTable = new DataTable();
        StoreTable.Columns.AddRange(new DataColumn[1]
        {
            new DataColumn("Name",typeof(string))                    
        });

        // 内部SQL逻辑省略:执行查询语句将门店结果加载到DataReader对象readerStore中

        if (readerStore.HasRows)
        {
            while (readerStore.Read())
            {  
                StoreTable.Rows.Add(readerStore["Name"].ToString());                            
            }
        }
        gvStore.DataSource = StoreTable;
        gvStore.DataBind();
        readerStore.Close();
    }
    catch (Exception ex)
    {
        OnErrorOccurred(new ErrorOccurredEventArgs("Grid View Bind Message" + ex.Message, ex));
    }
}

错误原因与修复方案

错误和索引值、DataKey配置无关,核心诱因是ASP.NET WebForms页面生命周期下,GridView数据绑定/状态加载时机错误:

  1. 未正确处理页面回发时的GridView数据加载逻辑:如果仅在首次页面加载、或点击其他按钮时调用GridViewStore()绑定数据,点击选择按钮触发回发后,RowCommand事件执行前,GridView未从视图状态恢复行数据、也未重新执行绑定,此时gvStore.Rows集合长度为0,传入任何合法索引都会触发超出范围错误。
  2. GridView初始设置了Visible="false",如果回发时控件仍处于隐藏状态,部分.NET框架版本不会初始化行集合,也会导致该错误。

修复操作:

  • 在Page_Load事件中补充绑定逻辑,首次加载时完成数据绑定,同时确认GridView开启视图状态(默认开启,无需额外修改),让回发时控件自动从视图状态恢复行数据:
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // 首次页面加载时绑定门店数据
        GridViewStore();
    }
}
  • 调整事件执行顺序:如果业务逻辑是点击其他按钮才显示门店GridView,要先设置gvStore.Visible = true、完成数据绑定,再响应行选择的RowCommand事件,不要在选择事件触发后才绑定数据或显示控件。
  • 替换取值逻辑:既然已经配置了DataKeyNames="Name",不需要从单元格读取文本,直接通过DataKey集合获取值即可,既不受Rows集合加载时机影响,也能避免单元格索引调整导致的取值错误:
protected void gvExecSelectSTR_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "SelectStore")
    {
        int index = Convert.ToInt32(e.CommandArgument);
        IDStore.Text = gvStore.DataKeys[index].Value.ToString();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:45:40