2015-11-15 2 views
0

Я пытаюсь понять, почему я получаю это сообщение об ошибке, и это заставляет меня встать на поверхность, потому что я думаю, что я применили все, что необходимо для получения желаемого результата. Что я могу сделать для этого.Я продолжаю получать «Неверную попытку прочитать, когда данных нет», хотя я уверен, что существует запись

private void btnLogin_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      // Receive user input from login screen 
      string username = txtUsername.Text; 
      string password = txtPassword.Text; 

      // Test if user input is null or white space aka empty 
      if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) 
       MessageBox.Show("Please enter both username and password"); 
      else 
      { 
       // Establish connection with database 
       SqlConnection cn = new SqlConnection(@"SERVER=KACY-PC\SQLEXPRESS2014;DATABASE=hardwareMgmt;Integrated Security=True"); 
       cn.Open(); 

       SqlCommand cmd = new SqlCommand(); 
       cmd.Connection = cn; 

       string strSQL = "SELECT * FROM tbl_user WHERE username = '" + username + "' AND password = '" + password + "'"; 
       cmd.CommandText = strSQL; 

       SqlDataReader dr = cmd.ExecuteReader(); 

       // Count number of record 
       int count = 0; 
       while (dr.Read()) 
        count += 1; MessageBox.Show(Convert.ToString(count)); 
       dr.Read(); 

       // Validate whether user has logged in before and display appropriate 
       if (count == 1 && dr["first_login"].ToString() == "N") 
        MessageBox.Show("Welcome back '" + dr["first_name"].ToString() + "' '" + dr["last_name"].ToString() + "'", "Welcome back", MessageBoxButtons.OK); 
       else if (count == 1 && dr["first_login"].ToString() == "Y") 
        MessageBox.Show("Hello " + dr["first_name"].ToString() + "' '" + dr["last_name"].ToString() + 
         "\nIt appears that you are logging in for the first time" + 
         "\nor your password got reset", "Welcome", MessageBoxButtons.OK, MessageBoxIcon.Information); 
       else if (count > 1) 
        MessageBox.Show("Duplication in user account \nPlease contact System Administrator", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
       else 
        MessageBox.Show("Invalid Username or Password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 

     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

Я продолжаю получать следующий результат после ввода учетных данных в окне входа в систему. Я уверен, что запись найдена в базе данных, но она просто не читает ее.

This is the error message I am getting after I login

+0

Да, я уверен, что он возвращает данные. Я проверил базу данных и даже распечатал счетчик записей, как указано в приведенном выше коде. Кроме того, я просто делаю это для школьного задания, которое должно состояться завтра. Но конечно, я также хотел бы знать, что вы имеете в виду, чтобы смягчить SQL Injection. – Kefash

ответ

3

Вашего

dr.Read(); 

линия не нужна, так как после того, как код

while (dr.Read()) 
    count += 1; MessageBox.Show(Convert.ToString(count)); 

, будет не следующей записи для чтения, поэтому вы получите эту ошибку.

Как сказал Иван, вы не можете прочитать данные после своего while. Вот почему, независимо от того, хотите ли вы читать first_login, first_name, last_name и т. Д. Столбцы, вы должны читать, пока выполняете итерирование своего читателя. Вот почему подумайте о том, чтобы сначала изменить свою логику.

И для себя я предпочитаю использовать GetXXX methods из SqlDataReader, когда я хочу прочитать значения вместо синтаксиса dr[...]. Это делает более читаемым, на мой взгляд.

Несколько вещей больше;

  • Вы всегда должны использовать parameterized queries. Этот тип конкатенаций строк открыт для атак SQL Injection.

  • Не храните свои пароли в виде простого текста. Read: Best way to store password in database

  • Используйте using statement, чтобы использовать ваше соединение, команду и считыватель автоматически.

+1

+1 Только для записи удаление ненужной строки не поможет, потому что он начнет получать другие исключения из 'dr [..]' операторов. Вся логика ошибочна. –

+0

@IvanStoev Право. Я обновил свой ответ на основе вашего комментария. Спасибо. –

+0

Спасибо, это действительно помогло. Прежде всего я должен сказать, что я вообще не учился в классе. Я применил все вышеперечисленное. 'параметризованный запрос',' using statements' и re обработали логику, чтобы нужные поля были захвачены во время 'while (dr.read())'. Единственное, что я не применял, это не сохранение пароля в базе данных в виде обычного текста. Причина в том, что это не требование для этого школьного задания. – Kefash