0

I have a login program that have a user name texbox and password textbox. The program should get the user's name and password from the user and matching it with the name and password that is available in the access database file. The file is in bin/debug folder. The problem is the while loop is not working and I am getting only "Incorrect username and password message" from the loop. Can anyone help me please? Here is my code:

private void loginButton_Click(object sender, EventArgs e)
{
     try
     {     
         connection.Open();
         OleDbCommand command = new OleDbCommand();
         command.Connection = connection;
         command.CommandText = "select * from login where UserName= '" + userTextBox.Text + "'and Password= '" + passwordTextBOx.Text + "'";
         OleDbDataReader reader = command.ExecuteReader();
         int count = 0;
         while (reader.Read())
         {
             count = count + 1;
         }
         if (count == 1)
         {
             this.Hide();
             Form newForm = new Form();// create new form
             newForm.Show();//display newform
         }
         if (count > 1)
         {
             MessageBox.Show("Duplicate UserName and Password");
         }
         else
         {
             MessageBox.Show("Incorrect UserName and Password");
         }
         connection.Close();
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
}
Slaven Tojić
  • 2,945
  • 2
  • 14
  • 33
S.R
  • 27
  • 2
  • 4
  • 2
    Try to add `else` before `if (count > 1)`. Now the message "Incorrect user name" will be displayed even when the name is found. And I would recommend to use `ShowDialog` instead of only `Show` to wait for the dialog to close before application continuing. – Julo May 18 '18 at 06:01
  • 9
    Your code has a ***serious sql injection vulnerability***, always use parameterized queries to avoid it. – Esko May 18 '18 at 06:02
  • Sorry, I am beginner in c# programming, I didn't get what you mean? – S.R May 18 '18 at 06:05
  • 2
    Is the password saved in a plain text? (Without hashing or using salt) – Lakshitha May 18 '18 at 06:05
  • 2
    Also you're not disposing correctly of resources. Wrap the reader and command in using statements. And close the connection in finally, not only when everything succeeds. – Jonas Høgh May 18 '18 at 06:06
  • Ok, I will try that – S.R May 18 '18 at 06:06
  • 1
    @S.R You should read a few articles about sql injection and parameterized queries. You can start here https://msdn.microsoft.com/en-us/library/ff648339.aspx or here https://stackoverflow.com/questions/14376473/what-are-good-ways-to-prevent-sql-injection – Esko May 18 '18 at 06:07
  • The password and the user name are saved in Access database file in bin/debug folder – S.R May 18 '18 at 06:07
  • @S.R: Like Esko told you - you have to use Parameters. Try the username `'; DROP DATABASE;` - won't be funny for you ;-) – kara May 18 '18 at 06:14
  • @S.R Apart from this bad style of code structure, I could only say is your count variable is always zero and the only possibility for that is the reader is empty which is obviously either username or password is incorrect. Please make sure both of them matches correctly. If possible add some screenshot of the credentials in the DB and the values in you send to the server. (In debug mode) – Lakshitha May 18 '18 at 06:15
  • Possible duplicate of [What are good ways to prevent SQL injection?](https://stackoverflow.com/questions/14376473/what-are-good-ways-to-prevent-sql-injection) – mjwills May 18 '18 at 06:21
  • It's bad to just swallow exceptions and throw up a message box. If ever you write `catch (Exception ex)` then you are being lazy. You should only catch exceptions that you can meaningfully handle. – Enigmativity May 18 '18 at 06:23

1 Answers1

4

If all you want is the number of rows returned, you should use SELECT COUNT(*) and ExecuteScalar:

command.CommandText = "select Count(*) from login where UserName= @Username and Password= @Password";
command.Parameters.AddWithValue("@Username", userTextBox.Text);
command.Parameters.AddWithValue("@Password", passwordTextBOx.Text);

OleDbDataReader reader = command.ExecuteScalar();

while (reader.Read())
{       
    count = reader.GetInt32(0);
}

Please note, that OleDb does not support named parameters. So while I named them @Username / @Password, these are in fact just placeholders. OleDb only uses positional parameters, so the order in which you add them to your query is important. Adding the password first, will give you a wrong result.

Marco
  • 22,856
  • 9
  • 75
  • 124