Dim con As New SqlConnection
con.ConnectionString = "Data Source=(local);Integrated Security=True"
Dim cmd As New SqlCommand("SELECT * FROM login where Admin = #Admin AND Password = #Password ", con)
'Set up parameters for the sqlcommand
cmd.Parameters.AddWithValue("#Admin", comb.Text)
cmd.Parameters.AddWithValue("#Password", Txtpass.Text)
'If the username or password is empty then throw an error
If comb.Text = String.Empty Then
MessageBox.Show("Please choose the username.", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
ElseIf Txtpass.Text = String.Empty Then
MessageBox.Show("Please enter the password.", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
Try
'Open the connection and declare an sqlreader
con.Open()
Dim reader As SqlDataReader = cmd.ExecuteReader
'If our reader has one or more rows then read those rows and compare the text
If reader.HasRows = True Then
reader.Read()
Dim ReadUserName As String
Dim ReadUserID As String
ReadUserID = reader(3) 'This is the first field returned, most likely UserID
ReadUserName = reader(1) 'This is the second field returned
'If the username and password match then it's a success
If comb.Text = reader("Admin").ToString And Txtpass.Text = reader.Item("Password").ToString Then
MessageBox.Show("Login successful" & ReadUserName)
Else
'If they don't match than throw an error
MessageBox.Show("Login Failed." & Environment.NewLine & _
"UserName and Password are casesensitive.", _
Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End If
Catch ex As Exception
MessageBox.Show(ex.ToString, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
con.Close()
End Try
End If
You're telling your code to read one row:
If reader.HasRows = True Then
reader.Read()
If you want to read all rows from your SqlDataReader, you need to use a loop (here in C#):
while (reader.Read())
{
..... (read the individual values for the current row) ......
}
The .Read() call will return true, as long as a row has been read from the SqlDataReader - now fetch the data from the row, store it or process it - whatever you need to do - and then your next call to reader.Read() checks if another row can be read. If so: repeat your processing.
If reader.Read() return false, then all rows have been read and you're done.
If command runs the code only once and read one row. So use while loop to read all the line
If reader.HasRows = True Then
While reader.Read()
Dim ReadUserName As String
Dim ReadUserID As String
ReadUserID = reader(3) 'This is the first field returned, most likely UserID
ReadUserName = reader(1) 'This is the second field returned
'If the username and password match then it's a success
If comb.Text = reader("Admin").ToString And Txtpass.Text = reader.Item("Password").ToString Then
MessageBox.Show("Login successful" & ReadUserName)
Else
'If they don't match than throw an error
MessageBox.Show("Login Failed." & Environment.NewLine & _
"UserName and Password are casesensitive.", _
Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End While ' I don't know much of vb.net'
End If
Related
Hello, I am trying to create a login system wherein there will be an admin and superadmin to login, I just followed some tutorials over the net and tried it on my own, I am new to vb and I just wanna try it out. However doing the codes below, it is not either logging in. It's always going to the catch part wherein it says it doesn't connect to the database. Here is the code error btw
A first chance exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles LoginBtn.Click
If userBox.Text = "" Or passwordBox.Text = "" Then
MessageBox.Show("Username and password are blank", "Authentication Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
Dim conn As New System.Data.OleDb.OleDbConnection()
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\ResortReservationSystem.accdb"
Try
Dim sql As String = "SELECT * FROM tbl_user WHERE username='" & userBox.Text & "' AND password = '" & passwordBox.Text & "'"
Dim sqlCom As New System.Data.OleDb.OleDbCommand(sql)
sqlCom.Connection = conn
conn.Open()
Dim sqlRead As System.Data.OleDb.OleDbDataReader = sqlCom.ExecuteReader()
If sqlRead.Item("userType") = "Admin" Then
MenuForm.Show()
Me.Hide()
ElseIf sqlRead.Item("userType") = "SuperAdmin" Then
EmployeeForm.Show()
Me.Hide()
Else
MessageBox.Show("Username and Password do not match.", "Authentication Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
userBox.Text = ""
passwordBox.Text = ""
userBox.Focus()
End If
Catch ex As Exception
MessageBox.Show("Failed to connect to Database..", "Database Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End If
End Sub
I changed your Or in the first If statement to an OrElse to short circuit the code from checking the second condition if it finds the first to be True.
Connections are precious objects and need to be closed and disposed. Open as late as possible and closed as soon as possible. Using...End Using blocks ensure this even if there is an error. In this case the command object is also included in the Using.
You can pass the connection string directly to the constructor of the connection. Likewise, pass the command text and the connection to the constructor of the command.
I changed the Select statement to only retrieve UserType because that is all that is used in the method. Don't pull more information than necessary from the database.
Learn to use Parameters. It makes the sql statement easier to write, speeds up the query and protects against sql injection.
Since we are only retrieving a single piece of data we can use .ExecuteScalar which gets the first column of the first row of the result set.
After the connection and command are closed and disposed with the End Using, we can deal with the data retrieved from the database.
Private Sub OpCode()
If userBox.Text = "" OrElse passwordBox.Text = "" Then
MessageBox.Show("Username and/or password are blank", "Authentication Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End If
Dim AdminType As String
Using conn As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\ResortReservationSystem.accdb"),
sqlComm As New OleDbCommand("SELECT UserType FROM tbl_user WHERE username= #User AND [password] = #Password", conn)
With sqlComm.Parameters
.Add("#User", OleDbType.VarChar, 100).Value = userBox.Text
.Add("#Password", OleDbType.VarChar, 100).Value = passwordBox.Text
End With
conn.Open()
AdminType = sqlComm.ExecuteScalar.ToString
End Using
If String.IsNullOrEmpty(AdminType) Then
MessageBox.Show("Username and Password do not match.", "Authentication Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
userBox.Text = ""
passwordBox.Text = ""
userBox.Focus()
ElseIf AdminType = "Admin" Then
MenuForm.Show()
Me.Hide()
ElseIf AdminType = "SuperAdmin" Then
EmployeeForm.Show()
Me.Hide()
End If
End Sub
I would be grateful if you could help me with a strange behavior on a vb.net project.
I have a Login form.
The user gives username and password and if the credentials are ok, the app goes to another form
Try
con.Open()
Dim sql As New SQLite.SQLiteCommand("Select * From users where username = '" & UsernameTextBox.Text & "' and userpass = '" & PasswordTextBox.Text & "'", con)
Dim dr As SQLite.SQLiteDataReader = sql.ExecuteReader
Dim dt As New DataTable
dt.Load(dr)
If dt.Rows.Count = 1 Then
'there is only one user
Dim f As New MainFrm
f.lbluser.Tag = dt.Rows(0)(3)
f.lbluser.Text = dt.Rows(0)(1)
f.ShowDialog()
Me.Close()
ElseIf dt.Rows.Count = 0 Then
'credentials are wrong
MessageBox.Show("No user with those credentials. Try again!", "Wrong credentials", MessageBoxButtons.OK, MessageBoxIcon.Error)
UsernameTextBox.Text = ""
PasswordTextBox.Text = ""
UsernameTextBox.Focus()
Exit Sub
Else
'credentials are multiple in the database
MessageBox.Show("Issues with the credentials. Code error: LFUE-1010", "Multiple users | LFUE-1010", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End If
con.Close()
Catch ex As Exception
con.Close()
'there are problems with the connection / or sql
MessageBox.Show("Connection issues - code error: LFDC-1020 " & ex.Message, "DB connection error | LFDC-1020", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
This works perfectly.
In the other form, let's say that I have a button:
If cbkeywords.SelectedIndex = -1 Then
MsgBox("select something")
Exit Sub
End If
Dim d = DirectCast(cbkeywords.SelectedItem, DataRowView).Item("Keyword")
If lstkeywords.Items.Count > 0 Then
For i As Integer = 0 To lstkeywords.Items.Count - 1
If lstkeywords.Items(i).contains(d) Then
MessageBox.Show("there is already value " & d, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
Else
dtkeys.Rows.Add(cbkeywords.SelectedValue, d)
lstkeywords.Items.Add(d)
End If
Next
Else
dtkeys.Rows.Add(cbkeywords.SelectedValue, d)
lstkeywords.Items.Add(d)
End If
if the code has an error then the app goes to Login Form Catch ex As Exception and get the message.
Wherever I have issues with code in different forms, the app goes to Login Form Catch ex As Exception.
I cleaned solution, project, restart but nothing changed.
Any ideas?
Thanks in advance
Do the database code first and then do the other code. Keep them separate. Otherwise, when you do f.ShowDialog(), it is still inside the Try...Catch.
Something like this:
Dim dt As New DataTable
Dim con As New SqliteConnection(yourConnectionString)
Try
Dim sql As New SQLite.SQLiteCommand("Select * From users where username = '" & UsernameTextBox.Text & "' and userpass = '" & PasswordTextBox.Text & "'", con)
Dim dr As SQLite.SQLiteDataReader = sql.ExecuteReader()
dt.Load(dr)
Catch ex As Exception
con.Close()
'there are problems with the connection / or sql
MessageBox.Show("Connection issues - code error: LFDC-1020 " & ex.Message, "DB connection error | LFDC-1020", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
If Sql IsNot Nothing Then
Sql.Dispose()
End If
If con IsNot Nothing Then
con.Dispose()
End If
End Try
If dt.Rows.Count = 1 Then
'there is only one user
Dim f As New MainFrm
f.lbluser.Tag = dt.Rows(0)(3)
f.lbluser.Text = dt.Rows(0)(1)
f.ShowDialog()
Me.Close()
ElseIf dt.Rows.Count = 0 Then
'credentials are wrong
MessageBox.Show("No user with those credentials. Try again!", "Wrong credentials", MessageBoxButtons.OK, MessageBoxIcon.Error)
UsernameTextBox.Text = ""
PasswordTextBox.Text = ""
UsernameTextBox.Focus()
Exit Sub
Else
'credentials are multiple in the database
MessageBox.Show("Issues with the credentials. Code error: LFUE-1010", "Multiple users | LFUE-1010", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End If
You do not need to open the connection because the .Load method does that and then leaves the connection in the state it was.
I have a Windows Form app that is not properly validating the user input information. Need some help.
I inserted the Microsoft Login form and am writing code to verify the user credentials. Using an Access DB to store and retrieve info. Two tables - one for email address and another for password.
I verify format of the email addy using regex. This works very well.
I validate the email address is in correct form and verify it is in the table (this works well). Then I attempt to read the password (appears this is not working as expected) and then read both bits of information from the tables. Next, I test to make sure both are present. If both are present control is passed to another form.
My issue is reading/verifying the password.
Here is my Visual Studio VB.net code.
Private Sub OK_Click(sender As System.Object, e As System.EventArgs) Handles OK.Click
Try
If MsgBox("Is your information correct?", MsgBoxStyle.YesNo, "M&P Records") = MsgBoxResult.Yes Then
Dim pattern As String = "^[A-Z][A-Z|0-9|]*[a-z][a-z|0-9|]*([_][a-z|0-9]+)*([.][a-z|0-9]+([_][a-z|0-9]+)*)?#[a-z][a-z|0-9|]*\.([a-z][a-z|0-9]*(\.[a-z][a-z|0-9]*)?)$"
Dim match As System.Text.RegularExpressions.Match = Regex.Match(txtUsername.Text.Trim(), pattern, RegexOptions.IgnoreCase)
If (match.Success) Then
Try
If i = 0 Then
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
'Change the following to your access database location
dataFile = "\11_2017_Spring\CSCI-2999_Capstone\DB_M&PRecords.accdb"
connString = provider & dataFile
myConnection.ConnectionString = connString
myConnection.Open()
i = 1
End If
Catch ex As Exception
' An error occured! Show the error to the user and then exit.
MessageBox.Show(ex.Message)
End Try
'the query:
Dim cmd As OleDbCommand = New OleDbCommand("SELECT * FROM [EmailAddress] WHERE [emailAddress] = '" & txtUsername.Text & "'", myConnection)
Dim com As OleDbCommand = New OleDbCommand("SELECT * FROM [Password] WHERE [Password] = '" & txtPassword.Text & "'", myConnection2)
Dim dr As OleDbDataReader = cmd.ExecuteReader()
Dim drp As OleDbDataReader = com.ExecuteReader()
' the following variable is hold true if EmailAddress is found, and false if EmailAddress is not found
Dim userFound As Boolean = False
' the following variable is hold true if Password is found, and false if Password is not found
Dim passwordFound As Boolean = False
' the following variables will hold the EmailAddress and Password if found.
Dim EmailAddressText As String = ""
Dim PasswordText As String = ""
'if found:
While dr.Read()
userFound = True
EmailAddressText = dr("EmailAddress").ToString
End While
While drp.Read()
passwordFound = True
PasswordText = drp("Password").ToString
End While
'checking the result
If userFound = True And passwordFound = True Then
frmMain.Show()
frmMain.Label1.Text = "Welcome " & EmailAddressText & " "
Else
MsgBox("Sorry, username or password not found", MsgBoxStyle.OkOnly, "M&P Records - Invalid Login")
With txtPassword
.Clear()
End With
With txtUsername
.Clear()
.Focus()
End With
End If
Else
MessageBox.Show("Please enter a valid email address", "M&P Records - Email Check")
With txtPassword
.Clear()
End With
With txtUsername
.Clear()
.Focus()
End With
End If
End If
Catch ex As Exception
' An error occured! Show the error to the user and then exit.
MessageBox.Show(ex.Message)
End Try
End Sub
Well first your approach isn't really safe due to the fact the the password isn't encrypted and that either there is no link between email and password ideally you would have table for example:
USER
--UID
--Email
PASS
--ID
--UID
--PASS
And you would hash your password for example sha512 furthermore for more security you would use Salt and certificates to secure the database connection.
Then you could do:
Hash current password in textbox and execute:
"SELECT USER.Email FROM USER,PASS WHERE USER.Email='TEXTBOX_EMAIL' AND USER.UID = PASS.UID"
Check if you have result if yes your connected.
However I tried to correct a bit what you did in the above code. Having used only SQLClient and not Olecommand i tried to keep what you did so there might be few syntax errors but should be ok:
Try
If MsgBox("Is your information correct?", MsgBoxStyle.YesNo, "M&P Records") = MsgBoxResult.Yes Then
Dim pattern As String = "^[A-Z][A-Z|0-9|]*[a-z][a-z|0-9|]*([_][a-z|0-9]+)*([.][a-z|0-9]+([_][a-z|0-9]+)*)?#[a-z][a-z|0-9|]*\.([a-z][a-z|0-9]*(\.[a-z][a-z|0-9]*)?)$"
Dim match As System.Text.RegularExpressions.Match = Regex.Match(txtUsername.Text.Trim(), pattern, RegexOptions.IgnoreCase)
If (match.Success) Then
Dim passwordFound As Boolean
Dim userFound As Boolean
Using con As New SqlClient.SqlConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source =\ 11_2017_Spring\CSCI-2999_Capstone\DB_M&PRecords.accdb")
'Using to make sure connection is disposed
'Open connection
con.Open()
'Prepare sql
Dim command As New OleDbCommand("SELECT [emailAddress] FROM [EmailAddress] WHERE [emailAddress] = '" & txtUsername.Text & "';", con)
'Create the reader
Dim reader As OleDbDataReader = command.ExecuteReader()
Dim Id As String = ""
' Call Read before accessing data.
While reader.Read()
'Get data
Id = reader(0)
End While
'Close Reader
reader.Close()
If Id <> "" Then
'User found
userFound = True
'Prepare the second sql
Dim command2 As New OleDbCommand("SELECT [Password] FROM [Password] WHERE [Password] = '" & txtPassword.Text & "';", con)
'Prepare second reader
Dim reader2 As OleDbDataReader = command.ExecuteReader()
Dim Pass As String = ""
' Call Read before accessing data.
While reader2.Read()
'Get tdata
Pass = reader2(0)
End While
reader.Close()
If Pass <> "" Then
'Pass found
passwordFound = True
Else
passwordFound = False
End If
Else
userFound = False
End If
'Close connection
con.Close()
'Clear connection pool
SqlConnection.ClearPool(con)
End Using
'checking the result
If userFound = True And passwordFound = True Then
frmMain.Show()
frmMain.Label1.Text = "Welcome " & EmailAddressText & " "
Else
MsgBox("Sorry, username or password not found", MsgBoxStyle.OkOnly, "M&P Records - Invalid Login")
With txtPassword
.Clear()
End With
With txtUsername
.Clear()
.Focus()
End With
End If
Else
MessageBox.Show("Please enter a valid email address", "M&P Records - Email Check")
With txtPassword
.Clear()
End With
With txtUsername
.Clear()
.Focus()
End With
End If
End If
Catch ex As Exception
' An error occured! Show the error to the user and then exit.
MessageBox.Show(ex.Message)
End Try
Decided to combine the email and passwords into one table. Made everything easier for now. Thanks for your help and suggestions.
I have two comboboxes, a messagebox and a Send button. When the app startups and I click on the Send button with the comboboxes and messagebox empty, a pop-up box comes up and says "Select a client" After doing this, I go back to the database and see that it has added a new record to that table, even though I didn't put in any data after clicking on the "Send" button. Same applies for when one of the three controls I have has data in it, but the other two don't, and the program asks me to enter that data before it succeeds. But it still adds the record despite having those If Statements. What am I doing wrong?
My code:
Using con As New SqlConnection(ConfigurationManager.ConnectionStrings("conStr").ConnectionString)
con.Open()
Using cmd As New SqlCommand
cmd.Connection = con
cmd.CommandText = "insert into tblMyTable(Client, UserName, Message) values('" & cboClient.Text & "', '" & cboUser.Text & "', '" & rtfMessage.Text & "')"
cmd.ExecuteNonQuery()
End Using
If cboClient.Text = "" Then
MsgBox("Select a client")
ElseIf cboUser.Text = "" Then
MsgBox("Select a user")
ElseIf rtfMessage.Text = "" Then
MsgBox("Enter a message")
Else
MsgBox("Message Sent")
End If
con.Close()
End Using
I think you want something like this (note this does not address parameterization concerns):
Using con As New SqlConnection(ConfigurationManager.ConnectionStrings("conStr").ConnectionString)
If cboClient.Text = "" Then
MsgBox("Select a client")
ElseIf cboUser.Text = "" Then
MsgBox("Select a user")
ElseIf rtfMessage.Text = "" Then
MsgBox("Enter a message")
Else
con.Open()
Using cmd As New SqlCommand
cmd.Connection = con
cmd.CommandText = "insert into tblMyTable(Client, UserName, Message) values('" & cboClient.Text & "', '" & cboUser.Text & "', '" & rtfMessage.Text & "')"
cmd.ExecuteNonQuery()
End Using
MsgBox("Message Sent")
End If
con.Close()
End Using
Similar solution to #OldProgrammer, with an attempt at parameterized insert.
Private Sub SendButton_Click(sender As System.Object, e As System.EventArgs) Handles SendButton.Click
Try
If writeMessage() Then
MessageBox.Show("Message sent.", "Success")
End If
Catch ex As Exception
MessageBox.Show(String.Concat("An error occurred sending this message:", ex.Message))
End Try
End Sub
Private Function writeMessage() As Boolean
If isValidMessage() Then
writeMessageInfo()
Return True
End If
Return False
End Function
Private Sub writeMessageInfo()
Using con As New SqlConnection(yourConnectionString)
con.Open()
Using cmd As New SqlCommand
cmd.Connection = con
cmd.Parameters.Add(New SqlParameter("clientValue", cboClient.Text))
cmd.Parameters.Add(New SqlParameter("userValue", cboUser.Text))
cmd.Parameters.Add(New SqlParameter("messageText", rtfMessage.Text))
cmd.CommandText = "insert into tblMyTable(Client, UserName, Message) values(#clientValuem, #userValue, #messageText)"
cmd.ExecuteNonQuery()
End Using
con.Close()
End Using
End Sub
Private Function isValidMessage() As Boolean
If cboClient.SelectedIndex = -1 Then
MessageBox.Show("Please select a client.", "Missing info")
cboClient.Focus()
Return False
End If
If cboUser.SelectedIndex = -1 Then
MessageBox.Show("Please select a user.", "Missing info")
cboUser.Focus()
Return False
End If
If rtfMessage.Text = String.Empty Then
MessageBox.Show("Please enter a message.", "Missing info")
rtfMessage.Focus()
Return False
End If
Return True
End Function
I have based my codes from my professors. I typed the right username and password but it keeps on saying invalid user. The name of the table is also correct. I don't know why it keeps on saying it's an invalid user kindly help me please.
If Len(Trim(txtUsername.Text)) = 0 Then
MessageBox.Show("Please enter user name", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
txtUsername.Focus()
Exit Sub
End If
If Len(Trim(txtPassword.Text)) = 0 Then
MessageBox.Show("Please enter password", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
txtPassword.Focus()
Exit Sub
End If
Dim query As String = "SELECT * FROM Users"
Dim dt As New DataTable
ExecuteQuery(query)
Dim ctr As Integer
If dt.Rows.Count > 0 Then
If (dt.Rows(ctr)("Username")) = txtUsername.Text Then
If (dt.Rows(ctr)("Password")) = txtPassword.Text Then
frmMainMenu.Show()
Me.Hide()
End If
Else
MsgBox("Incorrect password")
txtPassword.Text = ""
txtPassword.Focus()
End If
Else
MsgBox("Invalid user")
txtPassword.Text = ""
txtUsername.Text = ""
txtUsername.Focus()
End If
You are never initializing the dt DataTable. So a new DataTable will have 0 rows, and you will fall into the Else of If dt.Rows.Count > 0. I presume you had intended to have dt be the DataTable that results from the ExecuteQuery statement, but as you are neither passing dt in nor assigning a result from ExecuteQuery to the dt variable, it is still blank.
Not knowing what ExecuteQuery does, I would imagine it should be either
ExecuteQuery(query, dt)
or
dt = ExecuteQuery(query)
After which point you might fall into the intended username/password comparison block, if there are actually rows in the Users table.
However your matching still will not work unless the matching record is the first in the DataTable, as you never actually iterate/increment ctr.
this is my codes for ExecuteQuery()
Dim connectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\nikko\Documents\Visual Studio 2010\Projects\PayrollSystemThesis\PayrollSystemThesis\bin\Debug\Thesis.accdb"
Public Function ExecuteQuery(ByVal query As String) As DataTable
Try
Dim dbCon As New OleDbConnection(connectionString)
Dim dbDA As New OleDbDataAdapter(query, dbCon)
Dim dbCB As New OleDbCommandBuilder(dbDA)
Dim dbDT As New DataTable
dbDA.Fill(dbDT)
Return dbDT
Catch ex As Exception
MessageBox.Show(ex.Message)
Return Nothing
End Try
End Function
it reads sql statements.