【问题标题】:Gridview broke - Nothing ChangedGridview 坏了 - 没有任何改变
【发布时间】:2015-10-23 19:37:12
【问题描述】:

我正在 ASP.Net 中创建一个应用程序,团队领导可以在其中编辑特定项目的每小时目标。我计划今天向多个人展示这个项目,我调试了这个项目,以进行演练并练习我的演讲。

但是,问题出现了。我从 Gridview 检索要插入数据库的值的代码已损坏。

我收到的错误信息是:

“System.ArgumentOutOfRangeException”类型的异常发生在 System.Web.dll 但未在用户代码中处理

附加信息:指定的参数超出了有效值的范围。

我用来检索值的代码是:

 string contractName = gvShowData.DataKeys[e.RowIndex].Value.ToString();
 GridViewRow row = (GridViewRow)gvShowData.Rows[e.RowIndex];
 TextBox txtContractName = (TextBox)row.Cells[0].FindControl("Contract");
 string txtCName = ((TextBox)row.Cells[1].Controls[0]).Text;
 string txtModel = ((TextBox)row.Cells[2].Controls[0]).Text;
 string txtProcess = ((TextBox)row.Cells[3].Controls[0]).Text;
 string txtH0 = ((TextBox)row.Cells[4].Controls[0]).Text;
 string txtH1 = ((TextBox)row.Cells[5].Controls[0]).Text;
 string txtH2 = ((TextBox)row.Cells[6].Controls[0]).Text;
 string txtH3 = ((TextBox)row.Cells[7].Controls[0]).Text;
 string txtH4 = ((TextBox)row.Cells[8].Controls[0]).Text;
 string txtH5 = ((TextBox)row.Cells[9].Controls[0]).Text;
 string txtH6 = ((TextBox)row.Cells[10].Controls[0]).Text;
 string txtH7 = ((TextBox)row.Cells[11].Controls[0]).Text;
 string txtH8 = ((TextBox)row.Cells[12].Controls[0]).Text;
 string txtH9 = ((TextBox)row.Cells[13].Controls[0]).Text;
 string txtH10 = ((TextBox)row.Cells[14].Controls[0]).Text;
 string txtH11 = ((TextBox)row.Cells[15].Controls[0]).Text;
 string txtH12 = ((TextBox)row.Cells[16].Controls[0]).Text;
 string txtH13 = ((TextBox)row.Cells[17].Controls[0]).Text;
 string txtH14 = ((TextBox)row.Cells[18].Controls[0]).Text;
 string txtH15 = ((TextBox)row.Cells[19].Controls[0]).Text;
 string txtH16 = ((TextBox)row.Cells[20].Controls[0]).Text;
 string txtH17 = ((TextBox)row.Cells[21].Controls[0]).Text;
 string txtH18 = ((TextBox)row.Cells[22].Controls[0]).Text;
 string txtH19 = ((TextBox)row.Cells[23].Controls[0]).Text;
 string txtH20 = ((TextBox)row.Cells[24].Controls[0]).Text;
 string txtH21 = ((TextBox)row.Cells[25].Controls[0]).Text;
 string txtH22 = ((TextBox)row.Cells[26].Controls[0]).Text;
 string txtH23 = ((TextBox)row.Cells[27].Controls[0]).Text;

整个更新语句(删除了数据库连接字符串和表名)。

SqlConnection con = new SqlConnection(constring);

string contractName = gvShowData.DataKeys[e.RowIndex].Value.ToString();
GridViewRow row = (GridViewRow)gvShowData.Rows[e.RowIndex];
TextBox txtContractName = (TextBox)row.FindControl("Contract");
//string txtCName = row.Cells[1].Text;
//string txtModel = ((TextBox)row.Cells[2].Controls[0]).Text;
//string txtProcess = ((TextBox)row.Cells[3].Controls[0]).Text;
//string txtH0 = ((TextBox)row.Cells[4].Controls[0]).Text;
//string txtH1 = ((TextBox)row.Cells[5].Controls[0]).Text;
//string txtH2 = ((TextBox)row.Cells[6].Controls[0]).Text;
//string txtH3 = ((TextBox)row.Cells[7].Controls[0]).Text;
//string txtH4 = ((TextBox)row.Cells[8].Controls[0]).Text;
//string txtH5 = ((TextBox)row.Cells[9].Controls[0]).Text;
//string txtH6 = ((TextBox)row.Cells[10].Controls[0]).Text;
//string txtH7 = ((TextBox)row.Cells[11].Controls[0]).Text;
//string txtH8 = ((TextBox)row.Cells[12].Controls[0]).Text;
//string txtH9 = ((TextBox)row.Cells[13].Controls[0]).Text;
//string txtH10 = ((TextBox)row.Cells[14].Controls[0]).Text;
//string txtH11 = ((TextBox)row.Cells[15].Controls[0]).Text;
//string txtH12 = ((TextBox)row.Cells[16].Controls[0]).Text;
//string txtH13 = ((TextBox)row.Cells[17].Controls[0]).Text;
//string txtH14 = ((TextBox)row.Cells[18].Controls[0]).Text;
//string txtH15 = ((TextBox)row.Cells[19].Controls[0]).Text;
//string txtH16 = ((TextBox)row.Cells[20].Controls[0]).Text;
//string txtH17 = ((TextBox)row.Cells[21].Controls[0]).Text;
//string txtH18 = ((TextBox)row.Cells[22].Controls[0]).Text;
//string txtH19 = ((TextBox)row.Cells[23].Controls[0]).Text;
//string txtH20 = ((TextBox)row.Cells[24].Controls[0]).Text;
//string txtH21 = ((TextBox)row.Cells[25].Controls[0]).Text;
//string txtH22 = ((TextBox)row.Cells[26].Controls[0]).Text;
//string txtH23 = ((TextBox)row.Cells[27].Controls[0]).Text;

var list = new List<string>();

foreach(var cell in row.Cells)
{
    list.Add((cell.Controls[0] as TextBox).Text);
}


gvShowData.EditIndex = -1;
con.Open();

DateTime time = DateTime.Now;
string format = "yyyy-MM-dd HH:mm:ss.fff";

string commandString = "INSERT INTO dms (Contract, Line, Process, H0,H1,H2,H3,H4,H5,H6,H7,H8,H9,H10,H11,H12,H13,H14,H15,H16,H17,H18,H19,H20,H21,H22,H23,timestamp,username) VALUES('" + txtCName + "','" + txtModel + "','" + txtProcess + "','" + txtH0 + "','" + txtH1 + "','" + txtH2 + "','" + txtH3 + "','" + txtH4 + "','" + txtH5 + "','" + txtH6 + "','" + txtH7 + "','" + txtH8 + "','" + txtH9 + "','" + txtH10 + "','" + txtH11 + "','" + txtH12 + "','" + txtH13 + "','" + txtH14 + "','" + txtH15 + "','" + txtH16 + "','" + txtH17 + "','" + txtH18 + "','" + txtH19 + "','" + txtH20 + "','" + txtH21 + "','" + txtH22 + "','" + txtH23 + "','" + System.DateTime.Now.ToString(format) + "','" + User.Identity.Name.ToString() + "')";

SqlCommand com = new SqlCommand(commandString, con);
com.ExecuteNonQuery();
con.Close();
BindGridView();

【问题讨论】:

  • 不要使用Cell.FindControl,而是使用Row.FindControl。 Itemtemplate 中任何控件的NamingContainerGridViewRow,而不是单元格。这使它更具可读性且不易出错。
  • 正如错误提示 System.ArgumentOutOfRangeException 可能在索引 27 处没有任何单元格,但您仍然试图在数据绑定事件中访问它。请遵循@TimSchmelter 方法。
  • 我喜欢编程的众多原因之一是an error has arisen, but nothing changed 永远不会是真的。如果行为或执行路径发生变化,总会有某种变化。我的评论可能看起来没有建设性 - 但将其视为对可能引入错误的事情完全开放的建议。
  • 我还建议(在您的演示之后)您在代码审查中得到这个并花一些时间考虑替代方法。这些变量声明和实例化的重复性正在呼唤一个循环。
  • @Paul:始终使用 sql 参数而不是字符串连接来防止 sql 注入。

标签: c# asp.net gridview


【解决方案1】:

你可以重构这个:

 string txtCName = ((TextBox)row.Cells[1].Controls[0]).Text;
 string txtModel = ((TextBox)row.Cells[2].Controls[0]).Text;
 string txtProcess = ((TextBox)row.Cells[3].Controls[0]).Text;
 string txtH0 = ((TextBox)row.Cells[4].Controls[0]).Text;
 string txtH1 = ((TextBox)row.Cells[5].Controls[0]).Text;
 string txtH2 = ((TextBox)row.Cells[6].Controls[0]).Text;
 string txtH3 = ((TextBox)row.Cells[7].Controls[0]).Text;
 string txtH4 = ((TextBox)row.Cells[8].Controls[0]).Text;
 string txtH5 = ((TextBox)row.Cells[9].Controls[0]).Text;
 string txtH6 = ((TextBox)row.Cells[10].Controls[0]).Text;
 string txtH7 = ((TextBox)row.Cells[11].Controls[0]).Text;
 string txtH8 = ((TextBox)row.Cells[12].Controls[0]).Text;
 string txtH9 = ((TextBox)row.Cells[13].Controls[0]).Text;
 string txtH10 = ((TextBox)row.Cells[14].Controls[0]).Text;
 string txtH11 = ((TextBox)row.Cells[15].Controls[0]).Text;
 string txtH12 = ((TextBox)row.Cells[16].Controls[0]).Text;
 string txtH13 = ((TextBox)row.Cells[17].Controls[0]).Text;
 string txtH14 = ((TextBox)row.Cells[18].Controls[0]).Text;
 string txtH15 = ((TextBox)row.Cells[19].Controls[0]).Text;
 string txtH16 = ((TextBox)row.Cells[20].Controls[0]).Text;
 string txtH17 = ((TextBox)row.Cells[21].Controls[0]).Text;
 string txtH18 = ((TextBox)row.Cells[22].Controls[0]).Text;
 string txtH19 = ((TextBox)row.Cells[23].Controls[0]).Text;
 string txtH20 = ((TextBox)row.Cells[24].Controls[0]).Text;
 string txtH21 = ((TextBox)row.Cells[25].Controls[0]).Text;
 string txtH22 = ((TextBox)row.Cells[26].Controls[0]).Text;
 string txtH23 = ((TextBox)row.Cells[27].Controls[0]).Text;

阅读:

var list = new List<string>();

foreach(TableCell cell in row.Cells)
   list.Add((cell.Controls[0] as TextBox).Text);

然后,您如何分别检索这些值会有所改变。但是,由于您的变量名称似乎遵循严格的顺序,我认为按索引获取列表元素不是问题。

例如,现在不是myControl.Text = txtH0;,而是myControl.Text = list[0]; 如何获得“0”取决于您,它通常是循环的一部分。

有些人可能会说这并不能回答问题,而是代码审查 - 但它确实也解决了问题 - 现在也不例外了。

注意:请小心假设您的控件确实存在并且绝对是TextBox

【讨论】:

  • 此代码给出 > 严重性代码描述项目文件行错误 CS1061“对象”不包含“控件”的定义,并且没有扩展方法“控件”接受“对象”类型的第一个参数找到(您是否缺少 using 指令或程序集引用?) ARCManualUpdates A:\DEVELOPMENT\arc_manual_updates_v3\ARCManualUpdates\ARCManualUpdates\Default.aspx.cs 254
  • 我认为缩短代码中的TableCell 应该是GridViewCell - 或类似的。
  • 抱歉,由于我面前没有 IDE,因此我没有进行测试。随意编辑。
  • @JᴀʏMᴇᴇ 对不起。我也在空中编码(并考虑 Telerik)。看起来不错。但是您缺少var list = List&lt;string&gt;(); 中的一个新字符 - 不幸的是,我无法编辑的字符太少。
  • @ObsidianPhoenix - 抓到了!!
【解决方案2】:

我通过@JayMee 的回答得到了解决方案。

更新的新代码是:

        SqlConnection con = new SqlConnection(constring);
        string contractName = gvShowData.DataKeys[e.RowIndex].Value.ToString();
        GridViewRow row = (GridViewRow)gvShowData.Rows[e.RowIndex];
        TextBox txtContractName = (TextBox)row.FindControl("Contract");
        string txtCName = row.Cells[1].Text.ToString();
        string txtModel = row.Cells[2].Text.ToString();
        string txtProcess = row.Cells[3].Text.ToString();

        var list = new List<string>();

        for(int cell = 4; cell < 28; cell++)
        {
            list.Add((row.Cells[cell].Controls[0] as TextBox).Text.ToString());
        }

        gvShowData.EditIndex = -1;
        con.Open();

        DateTime time = DateTime.Now;
        string format = "yyyy-MM-dd HH:mm:ss.fff";

        string commandString = "INSERT INTO dms (Contract, Line, Process, H0,H1,H2,H3,H4,H5,H6,H7,H8,H9,H10,H11,H12,H13,H14,H15,H16,H17,H18,H19,H20,H21,H22,H23,timestamp,username) VALUES('" + txtCName + "','" + txtModel + "','" + txtProcess + "','" + list[0] + "','" + list[1] + "','" + list[2] + "','" + list[3] + "','" + list[4] + "','" + list[5] + "','" + list[6] + "','" + list[7] + "','" + list[8] + "','" + list[9] + "','" + list[10] + "','" + list[11] + "','" + list[12] + "','" + list[13] + "','" + list[14] + "','" + list[15] + "','" + list[16] + "','" + list[17] + "','" + list[18] + "','" + list[19] + "','" + list[20] + "','" + list[21] + "','" + list[22] + "','" + list[23] + "','" + System.DateTime.Now.ToString(format) + "','" + User.Identity.Name.ToString() + "')";

        SqlCommand com = new SqlCommand(commandString, con);
        com.ExecuteNonQuery();
        con.Close();
        BindGridView();

【讨论】:

  • 我不确定我是否在此处明确设置28,而是使用Cells.Count/Cells.Length(不确定是哪个)
  • 另外,我看到那里出现循环的另一个原因(列表项的串联)。从您开始重复自己的那一刻起-您通常会使用某种循环。事实上,你甚至可以使用join:dotnetperls.com/string-join
  • 你是对的 - 我可以在更新语句中使用 string.join 并从那里构建查询。我会在我的演讲之后看看这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-10
  • 2020-10-24
  • 2021-03-16
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
  • 1970-01-01
相关资源
最近更新 更多