错误:其他信息:索引(从零开始)必须大于或等于零并且小于参数列表的大小

本文关键字:小于 等于零 参数 列表 大于 索引 信息 其他 从零开始 错误 | 更新日期: 2023-09-27 18:28:44

给定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查询字符串中;这意味着您很容易受到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);

通过这种方式可以更容易地了解发生了什么。

既然你得到了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);

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

您的问题在这里:

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

从C#6开始,可以使用字符串插值,无需通过参数进行计数。

你的新电话可能是这样的:

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