【问题标题】:Error: Additional information: Index (zero based) must be greater than or equal to zero and less than the size of the argument list错误:附加信息:索引(从零开始)必须大于或等于零且小于参数列表的大小
【发布时间】:2012-04-07 00:55:47
【问题描述】:

鉴于 C# 代码,如下所示,附加到“.accdb”文件;当我运行它时,我收到消息:

mscorlib.dll 中出现“System.FormatException”类型的未处理异常附加信息:索引(从零开始)必须是 大于或等于零且小于参数的大小 列表。

发生了什么事?

public partial class Form1 : Form
    {
    OleDbConnection vcon = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;data source=C:\Hazardous Materials\KinneyDatabase.accdb");

        public Form1()
            {
                InitializeComponent();
            }

        private void Form1_Load(object sender, EventArgs e)
            {
                {
                    vcon.Open();
                }
                try
                {
                    StreamReader sr = new StreamReader(@"C:\Hazardous Materials\cities.txt");
                    string line = sr.ReadLine();

                    StreamReader sr2 = new StreamReader(@"C:\Hazardous Materials\drugs.txt");
                    string line2 = sr2.ReadLine();

                    while (line != null)
                    {
                        comboBox1.Items.Add(line);
                        line = sr.ReadLine();
                    }
                    while (line2 != null)
                    {
                        comboBox2.Items.Add(line2);
                        line2 = sr2.ReadLine();
                    }
                    {
                        textBox2.Text = "Date";
                    }
                }
            catch (System.Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
            }

        private void button1_Click(object sender, EventArgs e)
            {
                string addRemove = "";

                    if (radioButton1.Checked)
                        {
                            addRemove = radioButton1.Text;
                        }
                    else if (radioButton2.Checked)
                        {
                            addRemove = radioButton2.Text;
                        }
                {
                    MessageBox.Show("You have entered the following information: \n\n"
                        + " Date: " + textBox2.Text + "\n"
                        + " Store#: " + comboBox1.Text + "\n"
                        + " Medication: " + comboBox2.Text + "\n"
                        + " Quantity: " + textBox1.Text + "\n"
                        + " Initials: " + textBox3.Text + "\n"
                        + " Initials: " + addRemove);

                }

            }
        private void button2_Click(object sender, EventArgs e)
            {
                new Form2().Show();
            }

        private void button3_Click(object sender, EventArgs e)
            {
            Application.Exit();
            }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
            {
                MessageBox.Show("Scripted by Geoff Bertollini. March 2012");
            }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {

            }

        private void textBox2_TextChanged(object sender, EventArgs e)
            {
                var date = DateTime.Now.ToString("MM/dd/yyyy");
                textBox2.Text = date;
            }

        private void label4_Click_1(object sender, EventArgs e)
        {

        }

        private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            {
                string addRemove = "";

                if (radioButton1.Checked)
                {
                    addRemove = radioButton1.Text;
                }
                else if (radioButton2.Checked)
                    {
                        addRemove = radioButton2.Text;
                    }                   

                string vsql = string.Format("insert into Log values ({0}','{1}','{2}','{3}','{4}','{5}','{6}'),comboBox1.Text, comboBox2.Text, int.Parse(textBox1.Text), int.Parse(textBox1.Text), textBox2.Text, textBox3.Text, addRemove");
                OleDbCommand vcom = new OleDbCommand(vsql, vcon);
                vcom.ExecuteNonQuery();
                MessageBox.Show("The following data has been saved to the database: \n\n"
                        + "Date: " + textBox2.Text + "\n"
                        + "Store#: " + comboBox1.Text + "\n"
                        + "Medication: " + comboBox2.Text + "\n"
                        + "Quantity: " + textBox1.Text + "\n"
                        + "Initials: " + textBox3.Text);
                vcom.Dispose();
            }
        }
    }   
}

【问题讨论】:

  • 异常发生在代码的哪一行?
  • 还有一个可爱的 sql 注入漏洞。

标签: c#


【解决方案1】:

C# 6 string interpolation 开头是可用的,这样就无需计算参数。

您的新呼叫可能如下所示:

string vsql = $"insert into Log values ('{comboBox1.Text}','{comboBox2.Text}','{int.Parse(textBox1.Text)}','{int.Parse(textBox1.Text)}','{textBox2.Text}','{textBox3.Text}','{addRemove}')";

【讨论】:

    【解决方案2】:

    你的问题在这里:

    string vsql = string.Format("insert into Log values ({0}','{1}','{2}','{3}','{4}','{5}','{6}'),comboBox1.Text, comboBox2.Text, int.Parse(textBox1.Text), int.Parse(textBox1.Text), textBox2.Text, textBox3.Text, addRemove");
    

    应该是这样的:

    string vsql = string.Format("insert into Log values ({0}','{1}','{2}','{3}','{4}','{5}','{6}')",comboBox1.Text, comboBox2.Text, int.Parse(textBox1.Text), int.Parse(textBox1.Text), textBox2.Text, textBox3.Text, addRemove);
    

    【讨论】:

      【解决方案3】:

      您的应用程序中有一个小的格式错误和一个巨大的逻辑错误

      巨大的逻辑错误是您将用户输入的值直接传递到 SQL 查询字符串中;这意味着您很容易受到 SQL 注入的攻击

      这个小的格式错误在这里:

      string vsql = string.Format("insert into Log values ({0}','{1}','{2}','{3}','{4}','{5}','{6}'),comboBox1.Text, comboBox2.Text, int.Parse(textBox1.Text), int.Parse(textBox1.Text), textBox2.Text, textBox3.Text, addRemove");
      

      应该改为:

      string vsql = string.Format("insert into Log values ({0}','{1}','{2}','{3}','{4}','{5}','{6}')",comboBox1.Text, comboBox2.Text, int.Parse(textBox1.Text), int.Parse(textBox1.Text), textBox2.Text, textBox3.Text, addRemove);
      

      我将双引号从几乎从行尾移到{6} 后面一点。

      问题在于,正如所写的那样,整个巨大的字符串作为唯一的参数传递给String.Format,这意味着没有可用于替换的参数——因此出现了错误。

      我建议您改进代码格式,因为这种错误很容易避免。考虑如下格式:

      string vsql = string.Format(
          "insert into Log values ({0}','{1}','{2}','{3}','{4}','{5}','{6}')",
          comboBox1.Text,
          comboBox2.Text,
          int.Parse(textBox1.Text),
          int.Parse(textBox1.Text),
          textBox2.Text,
          textBox3.Text,
          addRemove);
      

      这样更容易看到发生了什么。

      【讨论】:

        【解决方案4】:

        既然你得到了System.FormatException,我会看看这行代码:

        string vsql = string.Format("insert into Log values ({0}','{1}','{2}','{3}','{4}','{5}','{6}'),comboBox1.Text, comboBox2.Text, int.Parse(textBox1.Text), int.Parse(textBox1.Text), textBox2.Text, textBox3.Text, addRemove");
        

        它可能应该类似于以下内容(格式化以使其更具可读性):

        string vsql = string.Format("insert into Log values " + 
            "('{0}','{1}','{2}','{3}','{4}','{5}','{6}')",
            comboBox1.Text, 
            comboBox2.Text, 
            int.Parse(textBox1.Text), 
            int.Parse(textBox1.Text),
            textBox2.Text,
            textBox3.Text,
            addRemove);
        

        您最初没有向格式数组提供任何元素,因为它们是字符串本身的一部分(这可能不是您想要的)。

        【讨论】:

          猜你喜欢
          • 2011-11-20
          • 2011-04-18
          • 2011-12-19
          • 2016-07-03
          • 2023-04-11
          • 2016-04-01
          • 2018-07-26
          • 1970-01-01
          相关资源
          最近更新 更多