On my application, I set up a MySQL connector and login system which queries a database on my local machine, and a NullReferenceException is thrown pointing at MySQLDataReader.Close()
within the Try
method. The CheckCredentials
function worked (almost) perfectly up until the point where I recreated the function and cleaned the code in its own module.
I did some debugging and it turns out that the exception is caused by:
If IsAlphanumeric(Username) = False Or IsAlphanumeric(Password) = False Then
ThrowException.InvalidCredentials()
Return False '<------ Right here!
End If
Which ultimately calls everything under Finally
, before MySQLDataReader
is initialized. But I don't think this should be the issue, as by calling MySQLDataReader.Close()
, MySQLDataReader
is already defined as MySqlDataReader
.
Definitions
Private Function IsAlphanumeric(Str As String) As Boolean
Return Regex.Match(Str.Trim(), "^[a-zA-Z0-9]*$").Success()
End Function
Private _
MySQLConnection As MySqlConnection,
MySQLQuery As MySqlCommand,
MySQLDataReader As MySqlDataReader
Private ReadOnly _
MySQLServer As String = "localhost",
MySQLSchema As String = "gauntlet",
MySQLTable As String = "accounts",
MySQLUsername As String = "root",
MySQLPassword As String = "root",
MySQLConnectionTimeout As Integer = 20
Code
Public Function CheckCredentials(Username As String, Password As String) As Boolean
Try
' Checks whether 'Username' and 'Password' are not alphanumeric and kills the operation.
' Helps prevent SQL injection.
If IsAlphanumeric(Username) = False Or IsAlphanumeric(Password) Then
ThrowException.InvalidCredentials()
Return False
End If
' MySQL connection string containing the required information in order to establish a connection to the database.
MySQLConnection = New MySqlConnection("Data Source=" & MySQLServer & ";" & _
"Database=" & MySQLSchema & ";" & _
"User ID=" & MySQLUsername & ";" & _
"Password=" & MySQLPassword & ";" & _
"Connection Timeout=" & MySQLConnectionTimeout.ToString)
' MySQL query to select all rows within columns of 'MySQLTable' with parameters username as 'Username' and password as 'Password'.
MySQLQuery = New MySqlCommand("SELECT * FROM " & MySQLTable & " WHERE username='" & Username & "' AND password='" & Password & "'", MySQLConnection)
' Establishes a connection between client computer and the database.
MySQLConnection.Open()
' Executes the previously defined MySQL query and reads the returned columns.
MySQLDataReader = MySQLQuery.ExecuteReader
' To execute whilst 'MySQLDataReader' is open for reading the returned results from 'MySQLQuery'.
While MySQLDataReader.Read
' Checks whether or not column 'admin' is set to 0 (False).
If MySQLDataReader.GetString(4) = "0" Then
ThrowException.PrivilegesNotMet()
Return False
End If
' Checks whether or not column 'banned' is set to 1 (True).
If MySQLDataReader.GetString(5) = "1" Then
ThrowException.AccountBanned(MySQLDataReader.GetString(6))
Return False
End If
' Checks whether or not strings 'Username' and 'Password' are valid matches to the returned rows' columns.
If Username = MySQLDataReader.GetString(1) And Password = MySQLDataReader.GetString(2) Then
Username = MySQLDataReader.GetString(1) ' Sets string 'Username' to the username as set in the table for the current account.
Password = MySQLDataReader.GetString(2) ' Sets string 'Password' to the password as set in the table for the current account.
Return True
Else
Username = Nothing ' Sets string 'Username' to nothing.
Password = Nothing ' Sets string 'Password' to nothing.
ThrowException.InvalidCredentials()
Return False
End If
End While
Catch ex As Exception
ThrowException.Database()
Finally
If MySQLDataReader.IsClosed = False Then
'======== NullReferenceException ======='
MySQLDataReader.Close() : End If ' Closes the data reader.
'======================================='
If MySQLConnection.State = System.Data.ConnectionState.Open = True Then
MySQLConnection.Close() : End If ' Closes the connection between the client and the database.
End Try
Return False
End Function