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

ASP.NET后台C#按钮第三次点击无响应问题求助

问题分析与解决方案

核心问题原因

  1. DataReader读取丢失数据:你先调用了rque.Read(),这会将DataReader的指针移动到第一行,之后dt.Load(rque)只会读取剩余的行,导致DataTable中缺少第一行数据。当计数变量c递增到等于DataTable的行数时,访问dt.Rows[c]会抛出索引越界异常,导致页面回发失败,按钮事件无法正常触发。
  2. 计数变量未持久化:c和qno是页面级字段,ASP.NET每次回发都会重新创建页面实例,这些变量会被重置。你当前前两次点击有效,大概率是初始值设为-1,但后续回发后变量状态丢失,或是异常导致逻辑中断。
  3. SQL注入风险:直接用字符串拼接SQL语句,存在严重的SQL注入漏洞,同时可能因为特殊字符导致查询失败。

修复后的代码示例

后台代码(修正版)

// 用ViewState持久化计数变量,避免回发重置
private int C
{
    get { return ViewState["C"] != null ? (int)ViewState["C"] : -1; }
    set { ViewState["C"] = value; }
}

private int Qno
{
    get { return ViewState["Qno"] != null ? (int)ViewState["Qno"] : 0; }
    set { ViewState["Qno"] = value; }
}

protected void NextButton_Click(object sender, EventArgs e)
{
    // 递增计数
    C++;
    Qno++;

    // 使用参数化查询,避免SQL注入
    string sql = "select * from questions where course=@course and [group]=@group and semester=@semester";
    using (SqlCommand lque = new SqlCommand(sql, con))
    {
        lque.Parameters.AddWithValue("@course", cour);
        lque.Parameters.AddWithValue("@group", gr);
        lque.Parameters.AddWithValue("@semester", sem);

        DataTable dt = new DataTable();
        try
        {
            con.Open();
            dt.Load(lque.ExecuteReader());
        }
        finally
        {
            con.Close();
        }

        // 检查是否还有数据可显示
        if (dt.Rows.Count > 0 && C < dt.Rows.Count)
        {
            QuestionNo.Text = Qno.ToString();
            DataRow row = dt.Rows[C];
            Question.Text = row.Field<string>(4);
            RadioButton1.Text = row.Field<string>(5);
            RadioButton2.Text = row.Field<string>(6);
            RadioButton3.Text = row.Field<string>(7);
            RadioButton4.Text = row.Field<string>(8);
        }
        else
        {
            // 无更多数据时的处理
            QuestionNo.Text = "已到最后一题";
            Question.Text = "";
            RadioButton1.Text = "";
            RadioButton2.Text = "";
            RadioButton3.Text = "";
            RadioButton4.Text = "";
            // 重置计数以便重新开始
            C = -1;
            Qno = 0;
        }
    }
}

关键修复点

  • ViewState持久化变量:将c和qno改为ViewState属性,确保回发时变量值不会丢失。
  • 移除多余的DataReader.Read():直接用dt.Load(lque.ExecuteReader())读取所有数据,避免丢失第一行。
  • 参数化SQL查询:替换字符串拼接为参数化查询,消除SQL注入风险,同时避免特殊字符导致的查询错误。
  • 索引越界检查:在访问DataTable行之前,先检查C是否小于总行数,避免抛出异常导致页面回发失败。
  • 资源释放:使用using块管理SqlCommand,确保数据库连接正确关闭。

额外建议

  • 可以将DataTable缓存到ViewState或Session中,避免每次点击都查询数据库,提升性能:比如第一次查询后将dt保存到ViewState,后续点击直接从ViewState读取。
  • 调试时可以在按钮事件开头添加断点,查看C的值和DataTable的行数,确认是否出现索引越界的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:18:26