【问题标题】:asp:SqlDataSource SelectCommand property does not persist when pagingasp:SqlDataSource SelectCommand 属性在分页时不持久
【发布时间】:2013-07-11 00:00:50
【问题描述】:

我有一个GridView (gvPart) 和一个SqlDataSource (sdsParts) 作为它的数据源。在gvPart,我拥有AllowPaging="true" 的属性。我还有一个TextBox (txtPartSearch) 和一个Button,用于通过gvPart 输入和执行搜索。为此,我在后面的代码中有以下内容:

protected void partSearch(object sender, EventArgs e)
{
    string query = txtPartSearch.Text;
    string selectCmd = "SELECT ... WHERE partnum LIKE '" + query + "%' ... "; // I have cut out most of the statement for clarity
    sdsParts.SelectCommand = selectCmd;
    gvPart.DataBind();
}

这样做的目的是允许用户输入零件编号,并让gvPart 仅显示与查询匹配的零件,而不是整个列表。

上述方法后gvPart的首页如预期。但是,如果这个select语句导致gvPart中的页面多于一页,则在页脚中点击page 2会显示第二页,但数据将来自原始数据的第2页(即最初的数据)在搜索之前拉取,在sdsParts 中使用默认的SelectCommand)。

似乎分页“重置”SqlDataSource 并使用写在 Default.aspx 中的 SelectCommand,而不管任何 sdsParts.SelectCommand = selectCmd 语句。

我尝试将SelectCommand 完全排除在外,因此sdsParts 看起来像这样:

<asp:SqlDataSource ID="sdsParts" runat="server" ConnectionString="..." />

然后在Page_Load中添加默认的:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string selectCmd = "SELECT ... ";
        sdsParts.SelectCommand = selectCmd;
        gvPart.DataBind();
    }
}

但随后单击gvPart 中的另一个页面使其变为空白,就像SelectCommand="" 一样。

为什么sdsPartsSelectCommand 会“重置”,我该如何解决/避免这种情况?

编辑

我已经解决了我的问题。对于那些来到这里遇到同样问题的人,请单击此处获取解释和解决方法的建议。

编辑将我上面的解决方案移至答案以更清晰

【问题讨论】:

    标签: c# asp.net gridview sqldatasource


    【解决方案1】:

    为什么要在后面的代码中更改 SqlDataSource 的 SelectCommand?将其放入控件中。

    其次,您的代码受到 SQL 注入攻击,请不要将用户提供的数据连接到您的 TSQL...永远。

    举个例子,一个快速的痛苦教训,去运行你的程序并输入下面的零件号';DROP TABLE PARTS;',然后在你哭完之后,如果你的老板没有解雇你,改变你的代码。

    【讨论】:

    • 我对此很陌生,我不知道如何避免这种攻击。我应该采取什么措施来预防?
    • 永远不要将你传递给数据库的字符串(尤其是来自用户的数据)连接在一起。
    • 您的 SqlDataSource 中应该有一个 SelectCommand,如下所示:SELECT ... FROM Parts WHERE partnum LIKE @partnum 然后创建一个名为 partnum 的 SqlParameter(可能是 ControlParameter)。
    • 我会那样做的。另外,我知道这并不一定构成一个安全的解决方案,但输入文本框的MaxLength 是 8。8 个字符不能做很多事情来搞砸一切
    • 如果您想让gridview 自动绑定到名为txtPartSearch 的控件,然后在SqlDataSource 中创建ControlParameter,告诉它从txtPartSearch 中提取值,并且不要将空字符串转换为null。将网格的数据源属性设置为 SqlDataSource 的 id,并删除所有隐藏代码。这一切都会发生在你身上。
    【解决方案2】:

    出于安全目的,SQLDataSource 不会维护任何新的SelectCommands。因此,SelectCommand 属性将恢复为.aspx 文件中编码的原始值。一种可能的解决方案是使用 Session 变量,如下所示:

    protected void partSearch(object sender, EventArgs e)
    {
        string query = txtPartSearch.Text;
        string selectCmd = "SELECT ... WHERE partnum LIKE '" + query + "%' ... ";
        sdsParts.SelectCommand = selectCmd;
        Session["select"] = selectCmd;
    }
    

    Page_Load:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Session["select"] != null)
            sdsParts.SelectCommand = selectCmd;
        else
            sdsParts.SelectCommand = "SELECT ... "; //some default command
    }
    

    Click here 了解更多信息并查看我的解决方案的位置。

    注意:不推荐我生成上述 select 语句的方法,因为它会引发 SQL 注入攻击。推荐使用SqlDataSource Parameters

    【讨论】:

      猜你喜欢
      • 2016-06-11
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 2019-06-15
      • 2017-01-10
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多