2

I create a question pool from where I choose random question to apply some algorithm, anyway when I debug the program I get Index was outside the bounds of the array error.

to have a clear idea about what I am talking about, here is my class for question:

Firstly I define class Gene represent question

public class Gene
{
    public string question { get; set; }
    public string CLO { get; set; }
    public string type { get; set; }
    public string Answer { get; set; }
    public string mark { get; set; }
    public string chapter { get; set; }
    public Gene(string s, string t, string i, string a, string m, string c)
    {
        this.question = s;
        this.type = t;
        this.CLO = i;
        this.Answer = a;
        this.mark = m;
        this.chapter = c;

    }
}
List<Gene> QuestionList = new List<Gene>();

then I bring question from database

protected void DropDownList5_SelectedIndexChanged(object sender, EventArgs e)
{
    string sub = DropDownList5.Text;


    SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Sondos\Downloads\For the project\suz\ExamGenerationSystem.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
    string s = "select * FROM QuestionBank WHERE (Cource_Code = '" + DropDownList5.SelectedItem.Text + "') ORDER BY RAND()";
        SqlCommand cmd = new SqlCommand(s, con);
        SqlDataReader dr;
        con.Open();
        dr = cmd.ExecuteReader();
        dr.Read();
        while (dr.Read())
        {
            string ques = dr["Question"].ToString();
            string questype = dr["Question_Type"].ToString();
            string quesCLO = dr["CLO"].ToString();
            string quesAnswer = dr["Answer"].ToString();
            string quesMark = dr["Mark"].ToString();
            string quesChapter = dr["Chapter"].ToString();
            QuestionList.Add(new Gene(ques, questype, quesCLO, quesAnswer, quesMark, quesChapter)); 
        }
}

then I make the question Pool

 Gene[] QuestionPool { get { return QuestionList.ToArray(); } }

and when I try to choose question randomly using this :

private System.Random randome;
private Gene GetRandomQuestion()
{
    int i = randome.Next(QuestionPool.Length);
    return QuestionPool[i];
}

the error Index was outside the bounds of the array was in line

 return QuestionPool[i];
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
Sondos
  • 61
  • 2
  • 10

2 Answers2

4

int i = randome.Next(QuestionPool.Length);

Here if QuestionPool is empty, then this becomes int i = randome.Next(0) which returns zero. Therefore,

return QuestionPool[i]; // Where i becomes 0

Will throw Index was outside the bounds as QuestionPool is empty and doesn't have anything at index 0.

So make sure that QuestionPool is not empty.


Some of the situations which will lead to QuestionPool being empty.

  1. No record in database which has Cource_Code = DropDownList5.SelectedItem.Text In this case while (dr.Read()) will be false on the first iteration and no Gene will be added to QuestionList.
  2. GetRandomQuestion is called before any Gene is added to QuestionList

Avoiding SQL Injection

This line is vulnerable to SQL Injection

(Cource_Code = '" + DropDownList5.SelectedItem.Text + "')

This means that if a user changes the SelectedItem's Text to something like

a'); Drop table QuestionBank; -- //Anything after -- becomes a comment

Then the query will become

select * FROM QuestionBank WHERE (Cource_Code = 'a'); Drop table QuestionBank;

And your table will be dropped.

To avoid this please refer to this answer.


Lists as Arrays

When you have lists, then you can also access its items by index. And to get its length you can use Count. Thus, GetRandomQuestion can become

private Gene GetRandomQuestion()
{
    int i = randome.Next(QuestionList.Count);
    return QuestionList[i];
}

And you won't require the QuestionPool, provided that you're using it only for this purpose.

Community
  • 1
  • 1
ZerosAndOnes
  • 1,083
  • 1
  • 13
  • 25
  • How can check that QuestionPool is not empty.? I put all relevant code if someone can see error in the rest of code. – Sondos Mar 25 '18 at 16:53
  • @Sondos which development environment are you using? Visual Studio? – ZerosAndOnes Mar 25 '18 at 17:05
  • In Visual Studio you check the values through the debugger https://www.youtube.com/watch?v=u-HdLtqEOog start from 03:00. I can explain it here, but I believe it's explained really well and in detail over there. The version might be different, but doesn't matter much. Regarding the places due to which QuestionPool might be empty please check my updated answer. – ZerosAndOnes Mar 25 '18 at 18:26
0

You just missed instantiate randome before you reference it.

private System.Random randome;
private Gene GetRandomQuestion()
{
    randome = new System.Random  // here
    int i = randome.Next(QuestionPool.Length);
    return QuestionPool[i];
}
KMC
  • 19,548
  • 58
  • 164
  • 253