0

I built a software that has a login form at the beginning where the user enters the username and the password and if the username and the password are correct a message is printed and the user has access to the program.

My problem is that this all works as it should but if the password or username is incorrect instead of my custom message i get a NullReferenceException.

If anyone has a guess what this could be please help me.

So far here is what i have tried :

private void Login()
{
    if (string.IsNullOrEmpty(textBoxKorisnickoIme.Text))
    {
        MessageBox.Show(@"Внеси корисничко име", "Порака", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }

    if (string.IsNullOrEmpty(textBoxLozinka.Text))
    {
        MessageBox.Show(@"Внеси лозинка", "Порака", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }

    try
    {
        var konekcija = Connection.prevzemiKonekcija();
        konekcija.Open();

        korisnik = textBoxKorisnickoIme.Text;
        password = textBoxLozinka.Text;
        var komanda = new MySqlCommand(
                "Select id from prodavnica.vraboteni where korisnik=@korisnik and lozinka=@lozinka", konekcija);

        komanda.Parameters.AddWithValue("@korisnik", korisnik);
        komanda.Parameters.AddWithValue("@lozinka", hc.NewHash(password)); ;

        int rezultat = (int) komanda.ExecuteScalar();

        if (rezultat > 0)
        {
            var meni1 = new Menu();
            prosledikorisnik();
            meni1.Show();
            Hide();
            NajavaTimeST();
            konekcija.Close();
        }
        else if(rezultat==0)
        {
            MessageBox.Show(@"Внесените корисничко име и или лозинка НЕ се валидни !", "Порака", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            attempt++;
            return;
        }

        if (attempt == 3)
        {
            MessageBox.Show("Пристапот е забранет!");
            System.Threading.Thread.Sleep(5000);
            return;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

If the user enters wrong password instead of printing "Внесените корисничко име и или лозинка НЕ се валидни !" i get the following message:

Object reference not set to an instance of an object.

Peter B
  • 22,460
  • 5
  • 32
  • 69
Timo Dimce
  • 21
  • 5

3 Answers3

2

This is happening because ExecuteScalar() returns null if the query finds no results (zero matching rows). And trying to cast null to an int will cause a NullReferenceException.

There are several fixes:

  • You can use object obj = ...ExecuteScalar(); and then check if obj is null or not before casting it to int.
  • You can cast the ExecuteScalar() outcome to int? which can handle null, meaning that the conversion will not crash anymore. And then check that result for null.
Peter B
  • 22,460
  • 5
  • 32
  • 69
2

The error is here:

int rezultat = (int) komanda.ExecuteScalar();

You are executing the query: Select id from... - it means that if the record will not be found (for example wrong password), ExecuteScalar() will return null.

So, you need check the result of ExecuteScalar(), and - if null - set rezultat to 0, like below:

var res = komanda.ExecuteScalar();
int rezultat = (res == null) ? 0 : (int)res;
VillageTech
  • 1,968
  • 8
  • 18
1

According to the documentation for ExecuteScalar(), it will return null if there is no match:

https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.executescalar?view=netframework-4.8

So to avoid the exception, you could cast instead to a nullable int:

var rezultat = (int?) komanda.ExecuteScalar();
AMA
  • 139
  • 1
  • 12