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

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();
        }
    }
}

关键修正点

  1. 移除参数的单引号包裹:将N' @forwardedSearchText '改为@forwardedSearchText,让SQL Server正确解析参数值。
  2. 增加列名白名单验证:防止forwardedSearchColumn被恶意篡改引发SQL注入,这是拼接列名时必须的安全措施。
  3. 优化参数处理:添加Trim()去除搜索文本的前后空格,同时处理null情况,避免参数值异常导致的查询问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:54:54