带分页的GridView搜索功能失效:SQL查询无法更新数据
问题分析与解决方案
核心问题
你遇到的问题根源有两个:
- 后台搜索逻辑操作的是
GridView1,但你要更新的目标控件是GridView3,完全对应错了对象 - 搜索查询的是
User_tbl,但GridView3初始绑定的是Ticket_tbl和Client_tbl的关联数据,查询表不匹配
另外你的代码存在SQL注入风险,而且手动绑定数据源后,GridView3的分页功能会失效——默认分页是基于SqlDataSource实现的。
修正方案
方案一:手动绑定并适配分页(适合自定义逻辑)
修改后台SearchButton1_Click方法,将目标改为GridView3,同时使用参数化查询规避注入风险,并且适配关联表的搜索逻辑:
protected void SearchButton1_Click(object sender, EventArgs e) { string searchText = SearchTextBox1.Text.Trim(); if (string.IsNullOrEmpty(searchText)) { Response.Write("<script>alert('من فضلك ادخل كلمة للبحث');</script>"); return; } try { using (SqlConnection Conn = new SqlConnection(strcon)) { // 适配GridView3初始的关联查询结构,加入搜索条件 string query = @"SELECT [Client_tbl].[client_fullname],[Ticket_tbl].[client_phone], [Client_tbl].[client_email],[Client_tbl].[client_company], [Client_tbl].[client_id_num],[Client_tbl].[client_tax_num], [Ticket_tbl].[ticket_category],[Ticket_tbl].[ticket_shortdetails], [Ticket_tbl].[ticket_details],[Ticket_tbl].[user_fullname], [Ticket_tbl].[user_branch],[ticket_date] FROM [Ticket_tbl] INNER JOIN [Client_tbl] ON [Ticket_tbl].[client_phone] = [Client_tbl].[client_phone] WHERE (Client_tbl.client_fullname LIKE @SearchText OR Ticket_tbl.ticket_shortdetails LIKE @SearchText OR Ticket_tbl.user_fullname LIKE @SearchText) ORDER BY [Ticket_tbl].[ticket_id] DESC"; SqlCommand cmd = new SqlCommand(query, Conn); // 参数化查询,彻底避免SQL注入 cmd.Parameters.AddWithValue("@SearchText", $"%{searchText}%"); SqlDataAdapter da = new SqlDataAdapter(cmd); DataSet ds = new DataSet(); da.Fill(ds); GridView3.DataSourceID = ""; GridView3.DataSource = ds; GridView3.DataBind(); } } catch (Exception ex) { // 转义单引号避免脚本报错 Response.Write($"<script>alert('{ex.Message.Replace("'", "\\'")}');</script>"); } }
如果要保留分页功能,需要重写GridView3_PageIndexChanging事件,并把绑定逻辑封装成复用方法:
protected void GridView3_PageIndexChanging(object sender, GridViewPageEventArgs e) { GridView3.PageIndex = e.NewPageIndex; // 重新绑定搜索数据 BindGridView3(SearchTextBox1.Text.Trim()); } // 封装GridView3的绑定逻辑 private void BindGridView3(string searchText) { using (SqlConnection Conn = new SqlConnection(strcon)) { string query = @"SELECT [Client_tbl].[client_fullname],[Ticket_tbl].[client_phone], [Client_tbl].[client_email],[Client_tbl].[client_company], [Client_tbl].[client_id_num],[Client_tbl].[client_tax_num], [Ticket_tbl].[ticket_category],[Ticket_tbl].[ticket_shortdetails], [Ticket_tbl].[ticket_details],[Ticket_tbl].[user_fullname], [Ticket_tbl].[user_branch],[ticket_date] FROM [Ticket_tbl] INNER JOIN [Client_tbl] ON [Ticket_tbl].[client_phone] = [Client_tbl].[client_phone]"; if (!string.IsNullOrEmpty(searchText)) { query += @" WHERE (Client_tbl.client_fullname LIKE @SearchText OR Ticket_tbl.ticket_shortdetails LIKE @SearchText OR Ticket_tbl.user_fullname LIKE @SearchText)"; } query += " ORDER BY [Ticket_tbl].[ticket_id] DESC"; SqlCommand cmd = new SqlCommand(query, Conn); if (!string.IsNullOrEmpty(searchText)) { cmd.Parameters.AddWithValue("@SearchText", $"%{searchText}%"); } SqlDataAdapter da = new SqlDataAdapter(cmd); DataSet ds = new DataSet(); da.Fill(ds); GridView3.DataSourceID = ""; GridView3.DataSource = ds; GridView3.DataBind(); } }
之后在SearchButton1_Click里调用BindGridView3(searchText),页面加载时调用BindGridView3("")完成初始化。
方案二:使用SqlDataSource参数化查询(更简洁,自动支持分页)
修改ASPX中的SqlDataSource3,添加参数配置,后台只需设置参数值即可:
ASPX代码:
<asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:Conn %>" SelectCommand="SELECT [Client_tbl].[client_fullname],[Ticket_tbl].[client_phone],[Client_tbl].[client_email],[Client_tbl].[client_company],[Client_tbl].[client_id_num],[Client_tbl].[client_tax_num],[Ticket_tbl].[ticket_category],[Ticket_tbl].[ticket_shortdetails],[Ticket_tbl].[ticket_details],[Ticket_tbl].[user_fullname],[Ticket_tbl].[user_branch],[ticket_date] FROM [Ticket_tbl] INNER JOIN [Client_tbl] ON [Ticket_tbl].[client_phone] = [Client_tbl].[client_phone] WHERE (@SearchText = '' OR Client_tbl.client_fullname LIKE @SearchText OR Ticket_tbl.ticket_shortdetails LIKE @SearchText OR Ticket_tbl.user_fullname LIKE @SearchText) ORDER BY [Ticket_tbl].[ticket_id] DESC"> <SelectParameters> <asp:Parameter Name="SearchText" Type="String" DefaultValue="" /> </SelectParameters> </asp:SqlDataSource> <asp:GridView ID="GridView3" runat="server" class="table table-bordered table-striped" AutoGenerateColumns="False" DataSourceID="SqlDataSource3" AllowPaging="true" PageSize="10" OnSelectedIndexChanged="GridView3_SelectedIndexChanged"></asp:GridView>
后台代码:
protected void SearchButton1_Click(object sender, EventArgs e) { string searchText = SearchTextBox1.Text.Trim(); if (string.IsNullOrEmpty(searchText)) { Response.Write("<script>alert('من فضلك ادخل كلمة للبحث');</script>"); return; } // 设置SqlDataSource的搜索参数 SqlDataSource3.SelectParameters["SearchText"].DefaultValue = $"%{searchText}%"; // 重新绑定数据 GridView3.DataBind(); }
这种方式不需要手动处理分页,SqlDataSource会自动适配分页逻辑,代码更简洁安全。
内容的提问来源于stack exchange,提问作者Alfahd Steel
相关产品推荐
相关产品推荐

