Log in page says user does not exist when they do - c#

I have a log in page that checks with a database for current registered users. At the moment my code will tell me me the user does not exist, when in fact they are on the database, or the page will remain the same if they aren't, when the text corresponding to the problem should come up.
So the name 'Tom' is already on the database, when i type 'Tom' i get the message
"user does not exist".
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SqlDataSource1_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
}
protected void Button_LogIn_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[#"\\MAC\HOME\DESKTOP\NIMV1.MDFConnectionString"].ConnectionString);
conn.Open();
string checkuser = "select count(*) from [Table] where UserName= '" + TextBoxLogIn.Text + "'";
SqlCommand com = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
if (checkuser == TextBoxLogIn.Text)
{
Session["New"] = TextBoxLogIn.Text;
Response.Write("User name is correct");
}
else
{
Response.Write("user does not exist");
}
conn.Close();
}
}

You're comparing your SQL string against the user name that has been passed in.
string checkuser = "select count(*) from [Table] where UserName= '" + TextBoxLogIn.Text + "'";
//...
if (checkuser == TextBoxLogIn.Text)
{
Session["New"] = TextBoxLogIn.Text;
Response.Write("User name is correct");
} else {
Response.Write("user does not exist");
}
I assume this will always evaluate to false unless the user has an SQL query for a name :D
[EDIT] Actually even if their name was an SQL query the code would never get to that point because you wouldn't find their name in the database in the first place.

You are comparing records using user name in database with entered text.
string checkuser = "select count(1) from [Table] where UserName= '" +
TextBoxLogIn.Text + "'";
After executing query instead of:
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
if (checkuser == TextBoxLogIn.Text)
///
///
Use following code:
if (temp >= 1)//if there is any user we will get temp >= 1
{
//conn.Open(); //No need to open connection again
//checkuser is SQL query so will never be equal to
//what user enters (like joe#example.com)
//if (checkuser == TextBoxLogIn.Text)
//{
Session["New"] = TextBoxLogIn.Text;
Response.Write("User name is correct");
//}
else //if no user with given name, temp will be 0
{
Response.Write("user does not exist");
//}
//conn.Close();
}

Peope already told you about the error you've made about comparing the variable that holds the query agains the value you typed (doh!!) but i want to DISCOURAGE you against writing the queries the way you do: it isn't a good practice to write query the way you've done because you are vulnerable to SQL Injection or at least nasty bugs if you don't escape correctly your variables.
I invite you to read about how to use what the .Net framework gives to you: use Parameters!
here you can find another answer with code that you can use or at least understand: https://stackoverflow.com/a/11905249/1716620

Related

c# Get ID from datatable on login

How can I save the UserID from the same datatable row whenever user inputs correct UserName and UserPassword? I want to use the saved GetUserID to another form.
Datatable 1 (Users):
UserID (IDENTITY 1 , 1)
UserName
UserPassword
My code:
private void button2_Click(object sender, EventArgs e)
{
if (textBox2.Text != string.Empty || textBox1.Text != string.Empty)
{
cmd = new SqlCommand("select * from Users where UserName='" + textBox1.Text + "' and UserPassword='" + textBox2.Text + "'; SELECT SCOPE_IDENTITY()", cn);
dr = cmd.ExecuteReader();
if (dr.Read())
{
dr.Close();
getUserID = Convert.ToInt32(cmd.ExecuteScalar());
form2 win_pagr = new form2();
this.Hide();
win_pagr.ShowDialog();
}
else
{
dr.Close();
MessageBox.Show("There is no user by this name or the password is incorrect!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show("Please fill the blanks!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
I Have tried using SCOPE_IDENTITY as you can see, It worked for something other I needed, but I doubt I need it here.
If the user already exists in the database you don't need that SELECT SCOPE_IDENTITY().
You have already the userid information in the DataReader.
So, supposing the UserID is the field where you keep that info then your code should be:
cmd = new SqlCommand(#"select UserID from Users
where UserName=#name
and UserPassword=#pwd", cn);
cmd.Parameter.Add("#name", SqlDbType.NVarChar).Value = TextBox1.Text;
cmd.Parameter.Add("#pws", SqlDbType.NVarChar).Value = TextBox2.Text;
object result = cmd.ExecuteScalar();
if (result != null)
{
getUserID = Convert.ToInt32(result);
form2 win_pagr = new form2();
this.Hide();
win_pagr.ShowDialog();
}
else
// User not found
Notice how I have removed the string concatenation in your query. This is a practice that leads to many errors from the simple syntax ones to the very dangerous Sql Injection hacking. The fix is always use Parameters to pass the values to the database engine.
There are other concerns in your code. It seems that you have a global connection object that you reuse in this code without opening it. This is another practice that is strongly discouraged. It creates resources problems on the server. Instead you should use a create/open/use/destroy pattern like
// create the connection
using(SqlConnection cn = new SqlConnection(....string to connect ....)
{
// Open the connection
// Use the connection
} // <= here the connection is destroyed
Another potential problem as highlighted in comments above is the storing of passwords in plain text. This is another very serious concern about the security of the database. You should use a hashing algorithm to store the resulting product of the hashing and not the clear password text.
See Best way to store passwords in a database

c# mysql query to If statement

So I'm trying to create simple button that decides if you are admin or user.
But I cant get it to work properly. I'm connected to MySQL db but when I click button with either admin/user account (stored in db) I get:
"you are an admin"
So I guess I have mistake somewhere but cant see where:
private void button1_Click(object sender, EventArgs e)
{
MySqlConnection cn = new MySqlConnection("Server=;Database=;Uid=;Pwd=;");
MySqlCommand cmd = new MySqlCommand("SELECT usertype FROM table1 ", cn);
cmd.Parameters.AddWithValue("usertype", usertype.Text);
cn.Open();
string usertype123 = cmd.ExecuteScalar()?.ToString();
if (usertype123 == "admin")
{
MessageBox.Show("you are an admin");
}
else
{
MessageBox.Show("You are an user ");
}
cn.Close();
}
If you don't add a WHERE statement to your sql command you will always retrieve the value from the first column of the first row returned by the database engine. You should change your code to something like this
private void button1_Click(object sender, EventArgs e)
{
// I assume you have a field named UserID as the primary key of your table1
string sqlCmd = #"SELECT usertype FROM table1 WHERE UserID=#id";
using(MySqlConnection cn = new MySqlConnection("....."))
using(MySqlCommand cmd = new MySqlCommand(sqlCmd, cn))
{
cmd.Parameters.Add("#id", MySqlDbType.Int32).Value = currentUserid;
cn.Open();
string usertype123 = cmd.ExecuteScalar()?.ToString();
if (usertype123 == "admin")
{
MessageBox.Show("you are an admin");
}
else
{
MessageBox.Show("You are an user ");
}
}
}
Now the problem is how to define the variable currentUserId This is something that you need to retrieve when the user logs in and conserve at the class level to reuse when needed. Notice also that connections are disposable objects and as such your need to dispose them as soon as you have finished to use them. The using statement helps to do this

System.Data.OleDb.OleDbException: 'Data type mismatch in criteria expression.'

I am new at coding and currently trying to make this barcode tracker program. So far I searched and found what i need but now I couldn't find the answer of this problem (or couldn't understand what people tried to say). So here is my problem:
I am using Ms Access as database but, as numeric datatype Access allows me to enter maximum 10 digit numbers. Also, I know that some barcodes include alphabetic characters so I have to change the datatype to text. If the column's datatype which contains the barcodes is numeric, program works. When i change the column's datatype to text, program gives data type mismatch error.
Here is my code:
public partial class Form1 : Form
{
OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\\Barcode\\Database.accdb; Persist Security Info=False");
OleDbDataReader DataReader;
OleDbCommand command;
bool flag = false;
public Form1()
{
InitializeComponent();
}
public void Form1_Load(object sender, EventArgs e)
{
}
public void txt_UPC_KeyDown(object sender, KeyEventArgs e)
{
if ((txt_UPC.Text == "") && (e.KeyCode == Keys.Enter))
{
e.Handled = true;
}
else
{
if (e.KeyValue == (char)Keys.Enter)
{
connection.Open();
string SelectQuery = "SELECT * FROM Products where [UPC]=" + txt_UPC.Text.ToString();
command = new OleDbCommand(SelectQuery, connection);
DataReader = command.ExecuteReader(); **//Error occurs here...**
while (DataReader.Read())
{
txtProduct.Text = DataReader["Product"].ToString();
txtPrice.Text = DataReader["Price"] + " ₺";
if (DataReader["UPC"].ToString() == txt_UPC.Text)
{
flag = true;
}
}
if (flag == true)
{
Test.Text = "Known Product";
txt_UPC.Text = "";
flag = false;
}
else
{
Test.Text = "Unknown Product";
}
connection.Close();
}
}
}
}
Suggest use apostrophe delimiters for text type field parameter.
string SelectQuery = "SELECT * FROM Products where [UPC]='" + txt_UPC.Text.ToString() + "'";
You need fully a formed SQL Server expression. You currently have
string SelectQuery = "SELECT * FROM Products where [UPC]=" + txt_UPC.Text.ToString();
Assuming that txt_UPC.Text is a string, you probably need to do this instead:
string SelectQuery = "SELECT * FROM Products where [UPC]= '" + txt_UPC.Text.ToString() + "'";
That encloses your string in the SQL-language mandated single quotes. For what it's worth, you probably don't need the .ToString() on that either.
And, it's a really bad idea to concatenate SQL like you are doing, particularly if you include user inputted text. Read up on "SQL Injection" and use parameterized SQL instead.

Check for existing value when adding to Access

I have an interface in which one of my functions include deleting a Serial Number from Access. If the Serial Number does exist then it deletes everything as it is supposed to with a confirmation message. The problem is, I can type in a Serial Number that does not exist and it acts like it is deleting it anyway. How do I check to see if the value exists when clicking the delete button, so I can then throw a notification to the user ?
private void btnDelete_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtSerial.Text))
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
string deleteEntry = "delete from Inventory where SerialNumber='" + txtSerial.Text + "' ";
DialogResult result = MessageBox.Show("ARE YOU SURE YOU WANT TO DELETE SERIAL NUMBER = " + txtSerial.Text + " ? ", "LAST CHANCE !", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
if (result.Equals(DialogResult.OK))
{
command.CommandText = deleteEntry;
command.ExecuteNonQuery();
MessageBox.Show("Data Has Been Deleted".PadLeft(28));
}
if (dataGridFB.DataSource != null)
{
dataGridFB.DataSource = null;
txtSerial.Clear();
comboSerial.Text = string.Empty;
comboPart.Text = string.Empty;
comboRO.Text = string.Empty;
comboLocation.Text = string.Empty;
comboSerial.Items.Clear();
comboPart.Items.Clear();
comboRO.Items.Clear();
comboLocation.Items.Clear();
}
else
{
dataGridFB.Rows.Clear();
}
ItemsLoad();
connection.Close(); // CLOSE HERE OR YOU CANNOT ENTER RECORDS SIMULTANEOUSLY
}
catch (OleDbException ex)
{
MessageBox.Show(ex.Message);
connection.Close();
}
}
The OleDbCommand.ExecuteNonQuery returns the number of rows affected by the command. If there is no row to delete the return value will be zero. So it is easy to discover this situation
int rowsDeleted = command.ExecuteNonQuery();
if(rowsDeleted == 0)
MessageBox.Show("No Serial number found to delete");
else
....
Said that, remember that string concatenation to build command text is considered bad practice and you should never use it. A parameterized query is the only correct way to create commands that requires inputs from the user.....
string deleteEntry = "delete from Inventory where SerialNumber=#num"
command.CommandText = deleteEntry;
command.Parameters.Add("#num", OleDbType.VarWChar).Value = txtSerial.Text;
int deletedRows = command.ExecuteNonQuery();
The OleDbCommand.ExecuteNonQuery method you're using returns an Int32 which represents the number of rows affected. You could use this to find out whether a row was deleted or not.
if (command.ExecuteNonQuery() > 0)
{
// Row was deleted
}
else
{
// Row was not deleted
}
You can do a Console.WriteLine("Nothing to delete") in an if based statement, but if it is compiled and you can not see the console, try a MessageBox.Show("Nothing to delete") function after an if based statement.
if (command.ExecuteNonQuery == 0)
{
Console.WriteLine("0-removed")
}
else
{
Console.WriteLine("not deleted")
As an example...
private void timer1_Tick(object sender, EventArgs e)
if (command.ExecuteNonQuery == 0)
{
Console.WriteLine("0-removed")
}
else
{
Console.WriteLine("not deleted")

Object reference not set to an instance of an object error when checking value from DB table

I am checking username from DB table when a user enters username in registration page an textbox OnTextChanged event fired which checks if username is already exists or not.
Here is code :
public void HandleTextbox1OnTextChanged(Object sender, EventArgs e)
{
string _connString = ConfigurationManager.AppSettings["connString"];
string username = txtUserName.Text;
int result = 0;
using (SqlConnection conn = new SqlConnection(_connString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("select * from ref_CourseRegistration_Users where nm_UserName=#nm_UserName", conn);
cmd.Parameters.AddWithValue("#nm_UserName", username);
cmd.ExecuteNonQuery();
result = (int)cmd.ExecuteScalar();
if (result > 0)
{
lblMessage.Text = "username already exists, please enter different User Name!";
lblMessage.ForeColor = Color.Red;
}
else
{
}
}
}
it works fine when username exists but when username doesn't exists it shows an error "Object reference not set to an instance of an object."
if i am missing anything?
You expect the number of users with the same name from your query, so you should select it:
Remove the line cmd.ExecuteNonQuery(); from your code, you already use cmd.ExecuteScalar(); and that's fine.
Your select should return a number, so you should select a number:
select COUNT(*) from ref_CourseRegistration_Users where nm_UserName=#nm_UserName
If you don't do this, you will get null from your query and that results in a null reference exception on your end because you don't handle it.

Categories