ASP.NET C#中ListView绑定参数化FreeText查询无结果求助
问题:ASP.NET C#参数化查询后ListView显示为空表
原本通过拼接SQL语句为ListView绑定数据可正常运行,改为参数化写法后程序无报错,但ListView显示空表,原代码与修改后代码如下:
原BindData方法
protected void BindData() { string forwardedSearchText = Request.QueryString["SearchText"]; string forwardedSearchColumn = Convert.ToString(Session["SearchTitle"]); string strsql = "Select TbSoore.IdSoore, TbSoore.NameSoore, TbAye.NumberAye, TbAye.IdAye, TbAye.TextAye, TbAye.TextTarjome From TbAye INNER JOIN TbSoore ON TbAye.IdSoore = TbSoore.IdSoore Where FreeText((" + forwardedSearchColumn + "),N' " + forwardedSearchText + "')"; DataTable dt = new DataTable(); using (SqlConnection con = new SqlConnection(strcon)) { using (SqlCommand cmdSQL = new SqlCommand(strsql, con)) { con.Open(); ListViewSearchResults.DataSource = cmdSQL.ExecuteReader(); ListViewSearchResults.DataBind(); } } }
修改后的BindData方法(存在问题)
protected void BindData() { string forwardedSearchText = Request.QueryString["SearchText"]; string forwardedSearchColumn = Convert.ToString(Session["SearchTitle"]); string strsql = $@"Select TbSoore.IdSoore, TbSoore.NameSoore, TbAye.NumberAye, TbAye.IdAye, TbAye.TextAye, TbAye.TextTarjome From TbAye INNER JOIN TbSoore ON TbAye.IdSoore = TbSoore.IdSoore Where FreeText(({forwardedSearchColumn}),N' @forwardedSearchText ')"; DataTable dt = new DataTable(); using (SqlConnection con = new SqlConnection(strcon)) { using (SqlCommand cmdSQL = new SqlCommand(strsql, con)) { cmdSQL.Parameters.Add("@forwardedSearchText", SqlDbType.NVarChar).Value = forwardedSearchText; con.Open(); ListViewSearchResults.DataSource = cmdSQL.ExecuteReader(); ListViewSearchResults.DataBind(); } } }
问题原因
修改后的SQL语句中,参数@forwardedSearchText被包裹在单引号N' @forwardedSearchText '里,这会导致SQL Server将其识别为字符串字面量(即查询内容是" @forwardedSearchText "这个固定字符串),而不是解析为传入的参数值,自然匹配不到任何数据,最终ListView显示为空。
另外,原代码中forwardedSearchColumn直接拼接进SQL,即使来自Session也存在SQL注入风险,建议后续通过白名单验证该字段的合法性。
修正后的代码
protected void BindData() { string forwardedSearchText = Request.QueryString["SearchText"]; string forwardedSearchColumn = Convert.ToString(Session["SearchTitle"]); // 验证列名合法性,避免SQL注入(示例:仅允许指定的列名) var allowedColumns = new List<string> { "TextAye", "TextTarjome", "NameSoore" }; if (!allowedColumns.Contains(forwardedSearchColumn)) { // 非法列名,设置默认值或抛出异常 forwardedSearchColumn = "TextAye"; } // 修正参数写法:移除参数周围的单引号,FreeText第二个参数直接使用参数 string strsql = $@"Select TbSoore.IdSoore, TbSoore.NameSoore, TbAye.NumberAye, TbAye.IdAye, TbAye.TextAye, TbAye.TextTarjome From TbAye INNER JOIN TbSoore ON TbAye.IdSoore = TbSoore.IdSoore Where FreeText({forwardedSearchColumn}, @forwardedSearchText)"; using (SqlConnection con = new SqlConnection(strcon)) { using (SqlCommand cmdSQL = new SqlCommand(strsql, con)) { // 指定参数长度并处理空值,避免潜在问题 cmdSQL.Parameters.Add("@forwardedSearchText", SqlDbType.NVarChar, 1000).Value = forwardedSearchText?.Trim() ?? string.Empty; con.Open(); ListViewSearchResults.DataSource = cmdSQL.ExecuteReader(); ListViewSearchResults.DataBind(); } } }
关键修正点
- 移除参数的单引号包裹:将
N' @forwardedSearchText '改为@forwardedSearchText,让SQL Server正确解析参数值。 - 增加列名白名单验证:防止
forwardedSearchColumn被恶意篡改引发SQL注入,这是拼接列名时必须的安全措施。 - 优化参数处理:添加
Trim()去除搜索文本的前后空格,同时处理null情况,避免参数值异常导致的查询问题。
内容的提问来源于stack exchange,提问作者Zahra
相关产品推荐
相关产品推荐

