Creating a login/register form - vb.net

I'm working on a vb form, which allows a person to create an "account". I store the usernames and passwords in two arrays, and extract the information from them. But when I run the program, it comes up with a problem:
"An unhandled exception of type 'System.ArgumentNullException'
occurred in Microsoft.VisualBasic.dll, Additional information: Value
cannot be null."
where the code for the Button2/Register Button is (To be exact:
For i = 0 To (UBound(Usernames))
Could you help me out and tell me what to do differently/how to approach this situation? Here is the code:
Public Class Form1
Dim Usernames() As String
Dim Passwords() As String
Dim CurrName As String
Dim i As Integer
'Login button is pressed
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Index As Integer
CurrName = TextBox1.Text
For i = 0 To (UBound(Usernames))
If IfRepetition(Usernames, CurrName, i) = True Then
Index = Array.IndexOf(Usernames, TextBox1.Text)
If TextBox2.Text = Passwords(Index) Then
Form3.Show()
Me.Hide()
End If
Else
MsgBox("The username or password is incorrect", MsgBoxStyle.Critical)
End If
Next
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
CurrName = TextBox1.Text
' *** Error (apparently) happens here ***
For i = 0 To (UBound(Usernames))
If IfRepetition(Usernames, CurrName, i) = True Then
MsgBox("This username already exists!")
Else
ReDim Preserve Usernames(UBound(Usernames) + 1)
Usernames(UBound(Usernames)) = TextBox1.Text
ReDim Preserve Passwords(UBound(Passwords) + 1)
Passwords(UBound(Passwords)) = TextBox2.Text
End If
Next
End Sub
Private Function IfRepetition(ByRef Usernames() As String, CurrName As String, i As Integer) As Boolean
Dim j As Integer
'Checks for repetition of a username in the usernames array
IfRepetition = False
For j = 0 To (UBound(Usernames))
If Usernames(j) = CurrName Then
IfRepetition = True
Exit Function
End If
Next
End Function
End Class

The error you're getting is because UBound throws exception if the array is null.
Also using arrays for that isn't a good way, I recommend you use Dictionary for easier, shorter code.
Dim dic As New Dictionary(Of String, String) 'A new dictionary which handles usernames & passwords
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Login button
If String.IsNullOrWhiteSpace(TextBox1.Text) Then 'Check the entered username, if it's empty show error message and return ( don't continue )
MessageBox.Show("Enter the username")
Return
End If
If String.IsNullOrWhiteSpace(TextBox2.Text) Then 'Check the entered password, if it's empty show error message and return ( don't continue )
MessageBox.Show("Enter the password")
Return
End If
If Not dic.ContainsKey(TextBox1.Text) Then 'Check the entered username, if it doesn't exist show error message and return ( don't continue )
MessageBox.Show("The username is incorrect")
Return
End If
If dic(TextBox1.Text) <> TextBox2.Text Then 'Validate entered username and password, if it's wrong show error message and return ( don't continue )
MessageBox.Show("The password is incorrect")
Return
End If
Form3.Show() 'If none of above error messages appear which means the entered username and password are correct, show Form3 and hide this form
Me.Hide()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'create account button
If String.IsNullOrWhiteSpace(TextBox1.Text) Then 'Check the entered username, if it's empty show error message and return ( don't continue )
MessageBox.Show("Enter the username")
Return
End If
If String.IsNullOrWhiteSpace(TextBox2.Text) Then 'Check the entered password, if it's empty show error message and return ( don't continue )
MessageBox.Show("Enter the password")
Return
End If
If dic.ContainsKey(TextBox1.Text) Then 'Check the entered username, if it exists show error message and return ( don't continue )
MessageBox.Show("This username already exists")
Return
End If
dic.Add(TextBox1.Text, TextBox2.Text) 'If none of above error messages which means it's okay to create this account, Add the username & password to the dictionary
End Sub

Related

VB Entering a Non_Numeric value crashes the program

Please consider adding a description to this question to attract more helpful responses.
Public Class Form1
Private Sub BtnCalculateRevenue_Click(sender As Object, e As EventArgs) Handles BtnCalculateRevenue.Click
Dim intvalue As Integer = CInt(TxtInputClassA.Text)
Dim intvalue2 As Integer = CInt(TxtInputClassB.Text)
Dim intvalue3 As Integer = CInt(TxtinputClassC.Text)
Dim total As Double
Try
LblStatus.Text = String.Empty
LblClassAResult.Text = (intvalue * 15).ToString("c")
LblClassBResult.Text = (intvalue2 * 12).ToString("c")
LblClassCResult.Text = (intvalue3 * 9).ToString("c")
total = CDbl((intvalue * 15) + (intvalue2 * 12) + (intvalue3 * 9))
LblTotal.Text = total.ToString("c")
Catch
LblStatus.Text = "Please Enter a Number"
End Try
End Sub
Private Sub BtnExit_Click(sender As Object, e As EventArgs) Handles BtnExit.Click
Me.Close()
End Sub
Private Sub BtnClear_Click(sender As Object, e As EventArgs) Handles BtnClear.Click
TxtInputClassA.Clear()
TxtInputClassB.Clear()
TxtinputClassC.Clear()
LblClassAResult.Text = String.Empty
LblClassBResult.Text = String.Empty
LblClassCResult.Text = String.Empty
LblTotal.Text = String.Empty
End Sub
End Class
VB Entering a Non_Numeric value crashes the program
Validation is built right into Windows Forms so you should make use of it. If you want to force the user to enter numbers in each of three TextBoxes then you can do this:
Private Sub TextBoxes_Validating(sender As Object, e As ComponentModel.CancelEventArgs) Handles TextBox3.Validating, TextBox2.Validating, TextBox1.Validating
Dim tb = DirectCast(sender, TextBox)
If Not Integer.TryParse(tb.Text, Nothing) Then
'Select all the invalid text and highlight it.
tb.SelectAll()
tb.HideSelection = False
MessageBox.Show("Please enter a whole number",
"Invalid Input",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation)
'Remove highlight when TextBox is not focused.
tb.HideSelection = True
'Don't let the control lose focus while data is invalid.
e.Cancel = True
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If ValidateChildren() Then
'All data is valid so proceed.
Dim n1 = CInt(TextBox1.Text)
Dim n2 = CInt(TextBox2.Text)
Dim n3 = CInt(TextBox3.Text)
'...
End If
End Sub
The ValidateChildren method will raise the Validating event for every control on the form and return False if any fail validation, i.e. e.Cancel is set to True in any event handlers, so that ensures that even controls that never received focus will be validated before the data is used.
Its bombing out on your cast "CInt(*value*)" so you can fix the code a couple ways. You can move your try above the casts like...
Try
Dim intvalue As Integer = CInt(TxtInputClassA.Text)
Dim intvalue2 As Integer = CInt(TxtInputClassB.Text)
Dim intvalue3 As Integer = CInt(TxtinputClassC.Text)
Dim total As Double
LblStatus.Text = String.Empty
You can do a data validation on your inputs and exit if they aren't all numeric (put this above your Dim intvalue code)
For Each value As String In {TxtInputClassA.Text, TxtInputClassA.Text, TxtInputClassA.Text}
If Not IsNumeric(TxtInputClassA.Text) Then
LblStatus.Text = "Please Enter a Number"
Exit Sub
End If
Next
Instead of casting as an int, use the tryparse method on Int32...
Dim intvalue As Integer
If Not Int32.TryParse(TxtInputClassA.Text, intvalue) Then
Exit Sub
End If
Or you could intercept the keypresses on each text box so that only numbers can be entered
Private Sub TxtInputClassA_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TxtInputClassA.KeyPress
If Not Char.IsDigit(e.KeyChar) Then
e.Handled = True
End If
End Sub
You can make that routine universal and append the event handler for all three text boxes like...
Private Sub EnforceOnlyNumericKeyPresses(sender As Object, e As KeyPressEventArgs) Handles TxtInputClassA.KeyPress, TxtInputClassB.KeyPress, TxtInputClassC.KeyPress
If Not Char.IsDigit(e.KeyChar) Then
e.Handled = True
End If
End Sub
Choose your favorite or do all of them, lots of choices.
Replace your textboxes with NumericUpDown controls and retrieve their .Value for your calculation. NUDs don't allow non numeric input and can have a fixed number of decimal places which may also be useful in a financial context

I am looking to use textfiles to validate a username and password login

I am looking to use textfiles to validate a username and password in VB.NET.
I have the username validated but I can not validate the passsword and anything entered in txtpassowrd.text will result in a login.
The code I used is this:
Imports System.IO
Public Class frmReceptionist
Function IsInFile(ByVal person As String) As Boolean
If File.Exists("receptionistUser.txt") And File.Exists("receptionistPassword.txt") Then
Dim sr As StreamReader = File.OpenText("receptionistUser.txt")
Dim individual As String
Do Until sr.EndOfStream
individual = sr.ReadLine
If individual = person Then
sr.Close()
Return True
End If
Loop
sr.Close()
End If
Return False
End Function
Private Sub btnConfirm_Click(sender As Object, e As EventArgs) Handles btnConfirm.Click
'Determine if a person is in the file
Dim person As String = txtUsername.Text
If person <> "" Then
If IsInFile(person) Then
MessageBox.Show(person & " Welcome Receptionist", "Bia Duitse")
Me.Hide()
frmBiaDuitse.Show()
Else
MessageBox.Show(person & " Incorrect Login", "No")
End If
Else
MessageBox.Show("You must enter Details", "Information")
End If
txtUsername.Clear()
txtUsername.Focus()
End Sub
Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
Me.Hide()
frmSelectJob.Show()
End Sub
End Class
This is definitely not the way you should be doing this.
For learning purposes, you could load up your files into a Dictionary() like this:
Private Credentials As Dictionary(Of String, String)
Private Sub LoadCredentials()
If IsNothing(Credentials) Then
Credentials = New Dictionary(Of String, String)()
If File.Exists("receptionistUser.txt") And File.Exists("receptionistPassword.txt") Then
Dim users() As String = File.ReadAllLines("receptionistUser.txt")
Dim passwords() As String = File.ReadAllLines("receptionistPassword.txt")
If users.Length = passwords.Length Then
For i As Integer = 0 To users.Length - 1
Credentials.Add(users(i), passwords(i))
Next
End If
End If
End If
End Sub
Function IsInFile(ByVal person As String) As Boolean
LoadCredentials()
If Not IsNothing(Credentials) Then
Return Credentials.ContainsKey(person)
End If
Return False
End Function
Function Checkpassword(ByVal person As String, ByVal password As String) As Boolean
LoadCredentials()
If Not IsNothing(Credentials) Then
Return Credentials.ContainsKey(person) AndAlso password = Credentials(person)
End If
Return False
End Function

Visual Basic:TRY\CATCH exception handling issues

I am working on an employee database and am having issues with my TRY\CATCH for saving records as it pertains to exception handling. The issue I am experiencing is that it will run the TRY and ignore the CATCH, allowing invalid data to pass and save to the file. I am very new to visual basic and am unsure of why this is not working. Here is my code for the form:
Option Strict Off
Imports System.IO
Public Class frmEmployeeData
'Variable Declarations
Dim BlnisChanged As Boolean = False
Dim empFirstName As String
Dim empMiddleName As String
Dim empLastName As String
Dim empNumber As Integer
Dim empDepartment As String
Dim empTelephone As String
Dim empExtension As Integer
Dim empEmailAddress As String
Dim empSelection As String
Dim fileName As String
Dim intTryParse As Integer = 0
Private Sub frmEmployeeData_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Adds the department options to the combo box dropdown list
ComboBoxEmpDepartment.Items.Add("Accounting")
ComboBoxEmpDepartment.Items.Add("Administration")
ComboBoxEmpDepartment.Items.Add("Marketing")
ComboBoxEmpDepartment.Items.Add("MIS")
ComboBoxEmpDepartment.Items.Add("Sales")
End Sub
Sub ClearItems()
'Clears text boxes
txtFirstName.Clear()
txtMiddleName.Clear()
txtLastName.Clear()
txtEmployeeNumber.Clear()
ComboBoxEmpDepartment.ResetText()
txtTelephone.Clear()
txtExtension.Clear()
txtEmailAddress.Clear()
End Sub
Sub SaveItems()
Dim savedEmployeeFile As StreamWriter
Try
'Creates the employee file
savedEmployeeFile = File.CreateText(fileName)
'writes information entered by user into file
savedEmployeeFile.WriteLine(txtFirstName.Text)
savedEmployeeFile.WriteLine(txtMiddleName.Text)
savedEmployeeFile.WriteLine(txtLastName.Text)
savedEmployeeFile.WriteLine(txtEmployeeNumber.Text)
savedEmployeeFile.WriteLine(ComboBoxEmpDepartment.Text)
savedEmployeeFile.WriteLine(txtTelephone.Text)
savedEmployeeFile.WriteLine(txtExtension.Text)
savedEmployeeFile.WriteLine(txtEmailAddress.Text)
'Closes the file
savedEmployeeFile.Close()
BlnisChanged = False
'Clears the text boxes
ClearItems()
Catch ex As Exception
'Throws error if file could Not be created
MessageBox.Show("Unable To Create File. Please Try Again", "Error In Saving")
End Try
End Sub
Sub AppendToFile()
Dim savedEmployeeFile As StreamWriter
Try
'append to file
savedEmployeeFile = File.AppendText(fileName)
'writes information entered by user into file
savedEmployeeFile.WriteLine(txtFirstName.Text)
savedEmployeeFile.WriteLine(txtMiddleName.Text)
savedEmployeeFile.WriteLine(txtLastName.Text)
savedEmployeeFile.WriteLine(txtEmployeeNumber.Text)
savedEmployeeFile.WriteLine(ComboBoxEmpDepartment.Text)
savedEmployeeFile.WriteLine(txtTelephone.Text)
savedEmployeeFile.WriteLine(txtExtension.Text)
savedEmployeeFile.WriteLine(txtEmailAddress.Text)
MessageBox.Show("Employee saved successfully.", "Success")
'Closes the file
savedEmployeeFile.Close()
BlnisChanged = False
'Clears the text boxes
ClearItems()
Catch ex As Exception
MessageBox.Show("No file exists. Please select 'Save As' Option.", "Error In Saving")
End Try
End Sub
Private Sub btnSaveRecord_Click(sender As Object, e As EventArgs) Handles btnSaveRecord.Click
Dim savedEmployeeFile As StreamWriter
'EXCEPTION HANDLING
'verifies first name field content
If txtFirstName.Text = "" Then
MessageBox.Show("First name cannot be blank", "Invalid Entry")
End If
'verifies middle name field content
If txtMiddleName.Text = "" Then
MessageBox.Show("Middle name cannot be blank", "Invalid Entry")
End If
'verifies last name field content
If txtLastName.Text = "" Then
MessageBox.Show("Last name cannot be blank", "Invalid Entry")
End If
'verifies employee number field content
If txtEmployeeNumber.Text = "" Then
MessageBox.Show("Employee number cannot be blank", "Invalid Entry")
ElseIf Not (Integer.TryParse(txtEmployeeNumber.Text, intTryParse)) Then
MessageBox.Show("Employee number must be numeric", "Invalid Entry")
ElseIf CStr(txtEmployeeNumber.Text) < 0 Then
MessageBox.Show("Employee number must be positive", "Invalid Entry")
End If
'verifies department field content
If ComboBoxEmpDepartment.Text = "" Then
MessageBox.Show("Employee department cannot be blank", "Invalid Entry")
End If
'verifies telephone number field content
If txtTelephone.Text = "" Then
MessageBox.Show("Telephone number cannot be blank", "Invalid Entry")
ElseIf Not (Integer.TryParse(txtEmployeeNumber.Text, intTryParse)) Then
MessageBox.Show("Telephone number must be numeric", "Invalid Entry")
End If
'verifies extension field content
If txtExtension.Text = "" Then
MessageBox.Show("Extension cannot be blank", "Invalid Entry")
ElseIf Not (Integer.TryParse(txtExtension.Text, intTryParse)) Then
MessageBox.Show("Extension must be numeric", "Invalid Entry")
ElseIf CInt(txtExtension.Text) < 0 Then
MessageBox.Show("Extension must be positive", "Invalid Entry")
End If
'verifies email address field content
If txtEmailAddress.Text = "" Then
MessageBox.Show("Email Address cannot be blank", "Invalid Entry")
End If
'If no filename exists, will prompt save dialog box and prompt user to save as
If fileName = String.Empty Then
If sfdSave.ShowDialog = System.Windows.Forms.DialogResult.OK Then
fileName = sfdSave.FileName
SaveItems()
End If
'If filename exists, append item to file
Else
AppendToFile()
End If
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
'Clears all content currently within text boxes
txtFirstName.Clear()
txtMiddleName.Clear()
txtLastName.Clear()
txtEmployeeNumber.Clear()
ComboBoxEmpDepartment.ResetText()
txtTelephone.Clear()
txtExtension.Clear()
txtEmailAddress.Clear()
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
'Closes Program
frmUserSelection.Show()
Me.Visible = False
End Sub
Private Sub SaveFileDialog1_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles sfdSave.FileOk
End Sub
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
'Picture Obtained From:
'"User Add Icon-Shine Set: Add New User, Add User." Free Icons PNG. Accessed 14 October 2018. https://www.freeiconspng.com/img/2487
End Sub
End Class
A Catch block only executes if an exception is thrown from within the Try block. I don't see anything here which would cause that to happen. It appears as though you're misunderstanding this a bit.
Don't put validation logic in a Catch block. All that should go there is code to handle an exception if one occurs. For example, if the connection to a database fails because the database itself is offline, or if writing to a file fails because the file can't be found/opened.
Put your validation logic before you even make the attempt to save it. If the user input fails validation, don't attempt to save it. Instead, return an error to the user. Only if your custom validation passes would you then begin the Try, write to your data store, and handle an exception if one occurs.

Why is it only displaying one result

This program is supposed to accept in valid candidates for voting, add the names typed in a text box to a list box. In the list box the user may double click on the candidate they choose. After the tally button is clicked a list box displaying the candidates' Names and votes will appear along side the other list box.
My problem is that the lstTallies only displays the last voted candidate.
Below is my code
Public Class Form1
Dim maxVotes As Integer
Dim winner As String
Dim votes() As Integer
Dim index As Integer
Dim candidates As String
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
If Not isValidInput(txtNewCandidate.Text) Then
Exit Sub
End If
lstCandidates.Items.Add(txtNewCandidate.Text)
txtNewCandidate.Clear()
txtNewCandidate.Focus()
ReDim Preserve votes(index)
index += 1
End Sub
Private Function isValidInput(ByRef firstName As String) As Boolean
If IsNumeric(txtNewCandidate.Text) Or txtNewCandidate.Text = "" Then
MsgBox("Please input a valid candidate name.")
txtNewCandidate.Focus()
Return False
Else
Return True
End If
End Function
Private Sub btnTally_Click(sender As Object, e As EventArgs) Handles btnTally.Click
lstTallies.Visible = True
lblTally.Visible = True
lstTallies.Items.Add(lstCandidates.Text & " " & votes(lstCandidates.SelectedIndex))
End Sub
Private Sub lstCandidates_DoubleClick(sender As Object, e As EventArgs) Handles lstCandidates.DoubleClick
If lstCandidates.SelectedIndex = -1 Then
MsgBox("Select a candidate by double-clicking")
End If
votes(lstCandidates.SelectedIndex) += 1
MsgBox("Vote Tallied")
End Sub
End Class
Try this:
Assuming the index of the Candidate and his/her Vote are the same:
Private Sub btnTally_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnTally.Click
lstTallies.Visible = True
lblTally.Visible = True
For i = 0 To lstCandidates.Items.Count - 1
lstTallies.Items.Add(lstCandidates.Items(i).ToString & " - " & votes(i))
Next
End Sub
You cannot get the contents of the ListBox unless you iterate it.

.NET Main Menu Help

I'm trying to make a main menu which accepts user input and then checks inputted password for validity against passwords I hardcoded into an array.
Firstly, in the for loop, only the first password index is being checked. I'd like the inputted password to be checked against EACH password inside the ValidPasswords() array.
Second, My for loop isn't doing what I want it to do. I'd like to give the user 3 chances to enter a password... If he/she exceeds 3, it tells them they've tried 3 times and exits the form. Right now, it just loops 3 times and exits without giving the user a chance to try again. If I put a return statement in, it just keeps returning and doesn't loop 3 times.
Public Class frmMain
Dim ValidPasswords() = {"1234", "2222", "8918", "9911"}
'Dim ValidPWList As New List(Of String)
Dim pwIndex As Integer = 0
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' For pwIndex = 0 To ValidPasswords.Length 'TOTAL PASSWORDS
If txtPW.Text = ValidPasswords(pwIndex) Then
Else
For i = 0 To 2 '3 MAX ALLOWABLE ATTEMPT
MessageBox.Show("Invalid Password, Please try again.", "Invalid Credentials")
txtPW.Focus()
Next
MessageBox.Show("Exceeded 3 password attempts.")
Me.Close()
End If
If txtFNAME.Text = "" Then
MessageBox.Show("Please enter your name!", "Error")
'ElseIf txtPW.Text <> "1234" And txtPW.Text <> "2332" And txtPW.Text <> "0192" And txtPW.Text <> "2010" Then
'MessageBox.Show("Invalid Password, Please try again.", "Invalid Credentials")
Else
g_welcomeMessage = ("Welcome, " + txtFNAME.Text + " " + txtLNAME.Text + ", to Image Viewer 1.0")
frmImage.ShowDialog()
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MessageBox.Show("Thanks for trying me out!", "Goodbye")
Me.Close()
End Sub
Thanks!
You got things back to front there Daniel. I'll not bore you with advice on hardcoded passwords in your application and assume you're just trying to grasp the basics... I'll also assume .Net 4 because you haven't specified ;-)
I'm doing this by hand so excuse any minor syntax issues:
Public Class frmMain
Private validPasswords As List(Of String) = New List(Of String) From {"1234", "2222", "8918", "9911"}
Private failedAttempts As Integer = 0
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If String.IsNullOrWhitespace(txtFNAME.Text) Then
MsgBox("Please enter a name")
Return
End If
If ValidPasswords.Any(Function(x) String.Equals(txtPW.Text, x)) Then
' User has a name and entered a valid password...
g_welcomeMessage = ("Welcome, " + txtFNAME.Text + " " + txtLNAME.Text + ", to Image Viewer 1.0")
frmImage.ShowDialog()
Else
failedAttempts += 1
If failedAttempts = 3 Then
MessageBox.Show("Exceeded 3 password attempts.")
Me.Close()
End If
End If
End Sub
' The other method here...
End Class