1

I have a form with two textboxes and one Login button, the textbox for the username is called txtUsername, and the textbox for the password is called txtPasswd, with the button being btnLogin. I have inserted a username and password into my database called accountinfo, and now I would like to login and show a specific form(being frmProduct, if the user successfully logs in) if their login matches any login in my database, and if it doesn't match any login in the database, a msgbox is shown saying "Oops! The requested username does not exist in the database!" I'm stuck on how to set this up properly, here's what I have tried so far.

Imports MySql.Data.MySqlClient

Public Class frmLogin


Private Sub frmLogin_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim ServerString As String = "Server=localhost:8080;User Id=root;Password=;Database=accountinfo"
Dim SQLConnection As MySqlConnection = New MySqlConnection
End Sub

Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click

Dim dbconnection As MySqlConnection

Dim cmd As MySqlCommand = New MySqlCommand
Dim reader As MySqlDataReader



    dbconnection.Open()



    cmd.CommandText = "SELECT Status FROM accountinfo WHERE UserName = ?UserName AND Password = ?Password"
    cmd.Parameters.Add(New MySqlParameter("?UserName", txtUsername.Text))
    cmd.Parameters.Add(New MySqlParameter("?Password", txtPasswd.Text))
    cmd.Connection = dbconnection
    reader = cmd.ExecuteReader
    dbconnection.dispose()



    If reader.HasRows() Then
        MessageBox.Show("Login successful!", "Welcome")
        frmProduct.Show()
    Else 
        MessageBox.Show("Oops! Login unsuccessful!")
    End If

End Sub
End Class
Jcrow
  • 53
  • 2
  • 9
  • if the reader doesnt have rows, then "oops!" you need an else. You should also Dispose of some of those things. See http://stackoverflow.com/a/29187199/1070452 – Ňɏssa Pøngjǣrdenlarp Jan 17 '16 at 18:57
  • @Plutonix I added the else statement, as for the dispose() I think I added in the correct place, see OP for edited code. In my DB I have a username called user and password called test123, when I put those into the my username and password field, I get "An unhandled exception of type 'System.NullReferenceException' occurred in VisualBasicVaultFinal.exe" which highlights under dbconnection.open() Everything seems to be filled in, and I don't believe anything is NULL? – Jcrow Jan 17 '16 at 19:05
  • The Connection AndAlso DataReader AndAlso DbCommand objects should *all* be disposed of. Use `Using` blocks` as described in the link. You also need to learn about [Scope](http://stackoverflow.com/a/33249045/1070452) that connection object you creates exists in the form load event only, so it is Nothing (null) in the click event. Move it to the click event – Ňɏssa Pøngjǣrdenlarp Jan 17 '16 at 19:12
  • @Plutonix Sorry but your example of using is hard to follow along with my code, as for the connection statement I moved into into my btnLogin sub and it gives me an error about using a variable before declaring it, even though I am declaring it before I'm using it. See OP for edited code – Jcrow Jan 17 '16 at 19:32
  • its not a connection "statement" it is an `Object`. Objects need to have an instance created using `New` - you dont do that. `Dim` just declares an object variable. Move (not copy) all the code from form load to the click event. [Using on MSDN](https://msdn.microsoft.com/en-us/library/htd05whh.aspx) – Ňɏssa Pøngjǣrdenlarp Jan 17 '16 at 19:36
  • @Plutonix Sorry I'm just getting confused now, can you post what you mean exactly? I'm slowly destroying my project moving things around. Everything IS in the click event. – Jcrow Jan 17 '16 at 19:42

1 Answers1

1

For Form load:

Private Sub frmLogin_Load(sender As Object, 
                e As EventArgs) Handles MyBase.Load
' no code here.
' nothing interesting happens
End Sub

Click event/Log in:

Dim conStr = "Server=localhost:8080;User Id=root;Password=;Database=accountinfo"
Dim SQL = "SELECT `Status` FROM accountinfo WHERE UserName = @uname AND `Password` = @pword"

Dim frmP As New frmProduct

' this object will be closed and dispose @ End Using
Using dbCon As New MySqlConnection(conStr)
    ' the command object likewise
    Using cmd As New MySqlCommand(SQL, dbCon)

        dbCon.Open()
        cmd.Parameters.Add(New MySqlParameter("@uname", txtUsername.Text))
        cmd.Parameters.Add(New MySqlParameter("@pword", txtPasswd.Text))

        ' create a Using scope block for the reader
        Using rdr As MySqlDataReader = cmd.ExecuteReader

            If rdr.HasRows Then
                MessageBox.Show("Login successful!", "Welcome")
                frmP.Show()
            Else
                MessageBox.Show("Oops! Login unsuccessful!")
            End If
        End Using
    End Using           ' close/dispose command

End Using               ' close/dispose connection

Important Notes

Do not store passwords as plain text. Hash them.

You should create new accounts for the app to use to connect to the DB. Exposing the admin/root passwords on the World Wide Web to the Whole Wide World is a bad idea.

Do Not use Default form instances If the form class is named frmProduct create a New instance of it for use in the app. Forms are just classes. It says so at the top of each one:

Public Class frmLogIn

So use them to create form objects as shown.

Scope
Dim/Private declares variables and their Type. Thus, Dim dbconnection As MySqlConnection does not create a connection object. It just says 'I want to use a MySql connection and it will be named 'dbconnection''.

Where the Dim/Private/Public line occurs determines the Scope or where that variable/object exists. When declared inside an event sub as with your dbconnection, then that object exists only there.

To create a form/class level variable, declare them at the form level:

Public Class Form1
    Private SomethingINeedLater As String

SomethingINeedLater will be available anywhere in the form.

Code such as this:

Dim frmP As New frmProduct

Does both: Dim declares the object variable, New creates an instance of that class.

In VB just about everything that results in indentation creates a new Block Scope. So, anything you declare inside a Using / End Using block (e.g. Dim foo As String = "Ziggy") will exist only there. That is why I declared the frmProduct well before the code uses it.

Finally, both "Status" and "Password" are reserved words for MySql and all/nearly all databases, so I escaped it in the SQL. Avoid columns and tables which are Reserved Words to avoid having to escape them.

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • Thank you for this post, it's quite helpful. I added the code the way it seemed how you wanted it, but now VB complains that it cannot connect to the specified MySQL host, despite having the correct information in my server string and dbCon.open(). Apache and MySQL are both running, and for my signup form I can insert records into the database, so that form can connect. – Jcrow Jan 17 '16 at 20:11
  • I have no idea if you connection string and settings are correct. The way your code is, it would appear that you have a database named `accountinfo` AndAlso inside it is a table named `accountinfo` is that correct? – Ňɏssa Pøngjǣrdenlarp Jan 17 '16 at 20:19
  • no i saw that mistake, the table is named accountinfodb, so I changed it to that, the server string you put is the exact server string. After I changed the table name to what it was I get: "An unhandled exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in MySql.Data.dll Additional information: Unknown column 'Status' in 'field list'" Here's how my DB is setup: http://i.imgur.com/ggpEpmp.jpg – Jcrow Jan 17 '16 at 20:22
  • status is a reserved word too – Ňɏssa Pøngjǣrdenlarp Jan 17 '16 at 20:25
  • Should I remove it from the SQL Query? I don't have it anywhere else in my program. Nor is it anywhere in my Database? – Jcrow Jan 17 '16 at 20:27
  • if it is not in your DB, why is it in the SQL to `SELECT Status FROM ...`? yes remove it change it to `SELECT *...` but that may reveal a flaw in your app. What if you get more than one row back? – Ňɏssa Pøngjǣrdenlarp Jan 17 '16 at 20:31
  • I'm so dumb, I did that and now it works. Thank you very much for all the help you have given me, and bless your patience :) I've learned a lot of new things! – Jcrow Jan 17 '16 at 20:32