ASP.NET中GridView值跨页传递及RowCommand索引越界问题排查
嘿,我来帮你搞定这两个ASP.NET的GridView问题,咱们一个个捋清楚:
一、ASP.NET中把GridView的值传递到另一页面的几种实用方法
- 查询字符串(QueryString)传递:这是最常用的方式,适合传ID这类公开的单个值。比如在GridView的
RowDataBound事件里,给行内的按钮设置跳转链接,带上当前行的ID:
然后在reportview.aspx里用protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { Button btnGoToReport = (Button)e.Row.FindControl("btnGoToReport"); // 从数据源里取当前行的ID string rowId = DataBinder.Eval(e.Row.DataItem, "ID").ToString(); btnGoToReport.NavigateUrl = $"reportview.aspx?ID={rowId}"; } }Request.QueryString["ID"]就能拿到这个ID了。 - Session传递:如果要传多组敏感数据,用Session更合适。在GridView的
RowCommand事件里,把整行数据存到Session:
到了目标页面,直接从Session里取就行,记得用完后可以清空Session避免内存占用。protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName == "SelectRow") { int rowIndex = Convert.ToInt32(e.CommandArgument); GridViewRow row = GridView1.Rows[rowIndex]; // 把需要的字段存到Session,比如 Session["UserName"] = row.Cells[1].Text; Session["UserID"] = row.Cells[0].Text; Response.Redirect("reportview.aspx"); } } - Server.Transfer传递:这种方式不会改变浏览器地址栏,适合内部页面跳转。用
Server.Transfer("reportview.aspx")跳转后,在目标页面通过PreviousPage获取原页面的GridView:
不过要注意,这种方式只能在同目录或者子目录的页面间用,跨目录可能会有问题。// reportview.aspx里的代码 protected void Page_Load(object sender, EventArgs e) { if (PreviousPage != null) { GridView sourceGridView = (GridView)PreviousPage.FindControl("GridView1"); // 然后获取需要的行数据 } }
二、解决RowCommand事件里的“Index was out of range”报错
你遇到的这个索引越界错误,大概率是这几个原因导致的,咱们逐个排查:
- 按钮没正确设置CommandArgument
如果你是通过e.CommandArgument获取行索引,一定要在GridView的按钮控件里加上CommandArgument='<%# Container.DataItemIndex %>',比如:
要是没加这个,<asp:Button ID="btnEdit" runat="server" Text="编辑" CommandName="EditRow" CommandArgument='<%# Container.DataItemIndex %>' />e.CommandArgument就是空或者无效值,转成int后自然会超出GridView的行数范围。 - GridView数据绑定时机错误
很多人会犯这个错:在Page_Load里直接绑定数据,没加!IsPostBack判断。这样每次回发(比如点击RowCommand里的按钮)时,GridView都会重新绑定,导致行索引和之前的不匹配。正确的绑定方式应该是:protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 先获取registration.aspx传过来的ID string queryId = Request.QueryString["ID"]; if (!string.IsNullOrEmpty(queryId)) { BindReportGridView(queryId); // 你的绑定方法,用ID查数据库 } } } - 查询ID无效导致GridView无数据
如果registration.aspx传过来的ID是空或者数据库里查不到对应数据,GridView就是空的,这时候触发RowCommand肯定会找不到行索引。所以绑定前一定要先校验QueryString的ID:string queryId = Request.QueryString["ID"]; if (string.IsNullOrEmpty(queryId)) { // 提示用户无效的请求 lblMessage.Text = "无效的查询ID"; return; } // 再执行数据库查询和绑定 - 错误的RowIndex获取方式
别用GridView1.SelectedIndex来获取行索引(除非你先选中了行),也别手动计算索引。正确的做法就是通过按钮的CommandArgument传递DataItemIndex,然后在RowCommand里转换:protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName == "EditRow") { // 先判断CommandArgument是不是有效的数字 if (int.TryParse(e.CommandArgument.ToString(), out int rowIndex)) { // 再判断索引是否在GridView的行数范围内 if (rowIndex >= 0 && rowIndex < GridView1.Rows.Count) { GridViewRow row = GridView1.Rows[rowIndex]; // 接下来处理行数据 } else { lblError.Text = "无效的行索引"; } } } }
内容的提问来源于stack exchange,提问作者Sridhar
相关产品推荐
相关产品推荐

