While loop is not functioning correctly - c#

I have a login program that have a user name texbox and password textbox. The program should get the user's name and password from the user and matching it with the name and password that is available in the access database file. The file is in bin/debug folder. The problem is the while loop is not working and I am getting only "Incorrect username and password message" from the loop. Can anyone help me please?
Here is my code:
private void loginButton_Click(object sender, EventArgs e)
{
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "select * from login where UserName= '" + userTextBox.Text + "'and Password= '" + passwordTextBOx.Text + "'";
OleDbDataReader reader = command.ExecuteReader();
int count = 0;
while (reader.Read())
{
count = count + 1;
}
if (count == 1)
{
this.Hide();
Form newForm = new Form();// create new form
newForm.Show();//display newform
}
if (count > 1)
{
MessageBox.Show("Duplicate UserName and Password");
}
else
{
MessageBox.Show("Incorrect UserName and Password");
}
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

If all you want is the number of rows returned, you should use SELECT COUNT(*) and ExecuteScalar:
command.CommandText = "select Count(*) from login where UserName= #Username and Password= #Password";
command.Parameters.AddWithValue("#Username", userTextBox.Text);
command.Parameters.AddWithValue("#Password", passwordTextBOx.Text);
OleDbDataReader reader = command.ExecuteScalar();
while (reader.Read())
{
count = reader.GetInt32(0);
}
Please note, that OleDb does not support named parameters. So while I named them #Username / #Password, these are in fact just placeholders. OleDb only uses positional parameters, so the order in which you add them to your query is important. Adding the password first, will give you a wrong result.

Related

I am working on a New user registration form that only contains of 3 fields, Username, password and confirm password

I am working on a user registration form containing only 3 fields Username,password and confirm password. But when i insert data, if password is mismatching, the exception appears form mismatch but on clicking OK, the data is inserted into db.
what should i do that it only insert on matching password
private void btn_save_Click(object sender, EventArgs e)
{
try
{
conn.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = conn;
string query = "INSERT INTO Users (username,newpassword)values('" + txt_newusr.Text + "','" + txt_password.Text + "')";
if (txt_password.Text == "" || txt_cnfpw.Text == "")
{
MessageBox.Show("Please enter values");
return;
}
if (txt_password.Text != txt_cnfpw.Text)
{
MessageBox.Show("Password confirm password are not matching");
txt_cnfpw.Focus();
}
MessageBox.Show(query);
command.CommandText = query;
command.ExecuteNonQuery();
MessageBox.Show("Record Saved successfully");
conn.Close();
}
}
You should change it like that
if (txt_password.Text == txt_cnfpw.Text)
{
MessageBox.Show(query);
command.CommandText = query;
command.ExecuteNonQuery();
MessageBox.Show("Record Saved successfully");
}
You have to do lots of corrections to make this work properly, Corrections like the following:
Make use of parameterized queries instead for concatenated queries to avoid injection
Process insert only after client-side validations(empty check password match etc)
Make use of using for managing connections and commands
I have added an example below, please have a look
try
{
string query = "INSERT INTO Users (username,newpassword)values(#username,#newpassword)";
bool CanInsertNewUser = true;
if (txt_newusr.Text=="" || txt_password.Text == "" || txt_cnfpw.Text == "")
{
CanInsertNewUser = false;
MessageBox.Show("Please enter values");
}
if (txt_password.Text != txt_cnfpw.Text)
{
CanInsertNewUser = false;
MessageBox.Show("Password confirm password are not matching");
txt_cnfpw.Focus();
}
if (CanInsertNewUser)
{
using (OleDbConnection conn = new OleDbConnection("GiveYourConnectionStringHere"))
{
using (OleDbCommand command = new OleDbCommand())
{
conn.Open();
command.Connection = conn;
command.CommandText = query;
command.Parameters.Add("#username", OleDbType.VarChar).Value = txt_newusr.Text;
command.Parameters.Add("#newpassword", OleDbType.VarChar).Value = txt_password.Text;
command.ExecuteNonQuery();
}
}
MessageBox.Show("Success");
}
}
catch (Exception ex)
{
MessageBox.Show("OLEDB issues : " + ex.Message.ToString());
}
In both the success and failure cases you are attempting to commit the transaction.
Save statements should only be executed if the password is matching. Move the save statements inside the success block as follows.
if (txt_password.Text == txt_cnfpw.Text)
{
MessageBox.Show(query);
command.CommandText = query;
command.ExecuteNonQuery();
MessageBox.Show("Record Saved successfully");
}
else
{
MessageBox.Show("Password confirm password are not matching");
txt_cnfpw.Focus();
}

Select MySQL Data in C#

I want to login to the program using c#, with my username and password that's stored to the SQL Database in phpmyadmin.
This is what I have so far.
private void button1_Click(object sender, EventArgs e)
{
MySqlConnection connection;
string server = "localhost";
string database = "login";
string uid = "root";
string password = "";
string connectionString;
connectionString = "SERVER=" + server + ";" + "DATABASE=" +
database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
connection = new MySqlConnection(connectionString);
try
{
connection.Open();
if (connection.State == ConnectionState.Open)
{
connection.Close();
Form1 frm = new Form1(this);
frm.Show();
Hide();
}
else
{
MessageBox.Show("Database Connection Failed", "Epic Fail", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
}
}
catch (Exception ex)
{
MessageBox.Show("An Error Occured, Try again later.", "Epic Fail", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
}
}
It connects to the database, however I don't want it to show the form1 Until both a valid Username and Password have been entered.
I'm guessing I need to use SELECT * FROM but I'm not exactly sure how to go about it.
You can use this way to see if username and password match
MySqlCommand cmd = dbConn.CreateCommand();
cmd.CommandText = "SELECT count(*) from tbUser WHERE UserName = #username and password=#password";
command.Parameters.Add("#username", txtUserName.Text);
command.Parameters.Add("#password", txtPassword.Text);
var count = cmd.ExecuteScalar();
if(count>0)
//Logged In
Just to say, if you use a query like
cmd.CommandText = "SELECT count(*) from tbUser WHERE UserName = '"+txtusernam +"'";
You will be open to SQL Injection
Warning
As Steve mentioned in comments Passwords in clear text are a vulnerability of the same magnitude of string concatenation
you make try this one
using(var con = new MysqlConnection{ ConnectionString = "your connection string " })
{
using(var command = new MysqlCommand{ Connection = con })
{
con.Open();
command.CommandText = #"SELECT level FROM userTable WHERE username=#username, password=#password";
command.AddWithValue("#username", txtusername.Text);
command.AddWithValue("#password", txtpassword.Text);
var strLevel = myCommand.ExecuteScalar();
if(strLevel == DBNULL.Value || strLevel == Null)
{
MessageBox.Show("Invalid username or password");
return;
}
else
{
MessageBox.Show("Successfully login");
hide(); // hide this form and show another form
}
}
}
use below Query
Select * from UsersTable Where Username='"+username+"' AND password='"+password+"'
Then you can make a if condition that if your query contain a result (rows) then users authenticated (exists in Table)
Note:Select query may fetch multiple users having same userName and
password, its upto you to keep usersname unique in table

How to block user login before activation asp.net c#

I am new to C#. I have Activation Data Type Bit in my database default value 0.
My question is how can I block user to login before activation email send
after registration is completed the activation is null in database but still user can login how can I fix this problem please help.
Here is my code:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Loginbtn_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegisterConnectionString"].ConnectionString);
conn.Open();
string checkuser = "select count(*) from UserData where UserName='" + UserName.Text + "'";
SqlCommand com = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
string checkPasswordQuery = "select password from UserData where UserName='" + UserName.Text + "'";
SqlCommand passComm = new SqlCommand(checkPasswordQuery, conn);
string password = passComm.ExecuteScalar().ToString().Replace(" ", "");
if (password == Password.Text && UserName.Text == "Admin" )
{
Session["New"] = UserName.Text;
Response.Redirect("~/Admin/UserManager.aspx");
}
if (password == Password.Text)
{
Session["New"] = UserName.Text;
Response.Redirect("~/Account/UserPage.aspx");
}
else
{
invalidlbl.Text = "Please check your username and password";
}
}
}
Here is the image of my database:
You said activation is null in database. So, when user tried to login, fetch and check if the activation is still null in database and if so then just so a message to user saying activate your account first and redirect him/her to home page.
EDIT: per your comment, not going to give you full code but here is an example of what I am saying. BTW, consider using SQL Parameter to avoid SQL Injection attack.
string checkuser = "select count(*) from UserData where UserName=#uname and activation != null";
SqlCommand com = new SqlCommand(checkuser, conn);
com.Parameters.Add("#uname", SqlDbType.VarChar).Value = UserName.Text.Trim();
int temp = Convert.ToInt32(com.ExecuteScalar());
if(temp > 0)
{
// do processing
}
else
{
// not activated ... throw alert
}

Why I get syntax error in this update statement?

I wanted to update a table in my m/s access database where my the user entered a new password in order to replace the old one but i have syntax error in the update statement. Please help!
public partial class resetPassword : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SubmitButton_Click(object sender, EventArgs e)
{
string userName = (string) Session["username"];
string str = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\inetpub\wwwroot\JetStar\database\JetstarDb.accdb";
var con = new OleDbConnection(str);
con.Open();
string pwd = Request.Form["conPassword"];
OleDbCommand cmd = new OleDbCommand("UPDATE [users] SET password = '" + pwd + "' WHERE username = '" + userName + "'", con);
try
{
cmd.ExecuteNonQuery();
MessageBox.Show("Your password has been changed successfully.");
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
con.Close();
}
}
}
Probably this happends because password is a reserved keyword on Microsoft Access. You should use it with square brackets as [password]
But more important
You should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Don't store your passwords as a plain text. Read: Best way to store password in database
Use using statement to dispose your OleDbConnection and OleDbCommand.
using(OleDbConnection con = new OleDbConnection(str))
using(OleDbCommand cmd = con.CreateCommand())
{
cmd.CommandText = "UPDATE [users] SET [password] = ? WHERE username = ?";
cmd.Parameters.Add("pass", OleDbType.VarChar).Value = pwd;
cmd.Parameters.Add("user", OleDbType.VarChar).Value = userName;
con.Open();
try
{
cmd.ExecuteNonQuery();
MessageBox.Show("Your password has been changed successfully.");
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
92.3% (a) of all DB problems become obvious if you just print the command before you use it, and read the error message.
So replace:
OleDbCommand cmd = new OleDbCommand("UPDATE [users] SET password = '" + pwd + "' WHERE username = '" + userName + "'", con);
with something like:
String s = "UPDATE [users] SET password = '" + pwd + "' WHERE username = '" + userName + "'";
Console.WriteLine(s);
OleDbCommand cmd = new OleDbCommand(s, con);
Then post the results of:
Response.Write(ex.Message);
for all to see, and examine what it tells you very carefully.
(a) A statistic I just plucked out of nowhere - actual value may be wildly different.

How to check if SQL database already has the entered Username?

I've written this registration form which adds data to my SQL Server database. What I want is an exception when the user enters a username that is already in the database.
protected void Button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection conn2 = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn2.Open();
string CheckUser = "select Username from UserData where Username like #Username";
SqlCommand com2 = new SqlCommand(CheckUser, conn2);
com2.Parameters.AddWithValue("#Username", "'%"+ UsernameTextBox.Text +"%'");
com2.ExecuteNonQuery();
int IsMatch = Convert.ToInt32(com2.ExecuteScalar().ToString());
conn2.Close();
if (IsMatch == 0)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
string InsertQuery = "insert into UserData (Username, Email, Password, Country) values (#Username, #Email, #Password, #Country)";
SqlCommand com = new SqlCommand(InsertQuery, conn);
com.Parameters.AddWithValue("#Username", UsernameTextBox.Text);
com.Parameters.AddWithValue("#Email", EmailTextBox.Text);
com.Parameters.AddWithValue("#Password", PasswordTextBox.Text);
com.Parameters.AddWithValue("#Country", CountryDropDownList.SelectedItem.ToString());
com.ExecuteNonQuery();
Response.Redirect("Manager.aspx");
conn.Close();
}
else
{
Response.Write("User Already Exists!");
}
}
catch (Exception ex)
{
Response.Write(Convert.ToString(ex));
}
}
When I run it, I get an exception on the following line:
int IsMatch = Convert.ToInt32(com2.ExecuteScalar().ToString());
Blam's second solution works, but the IsMatch can be simplified a bit by casting to int instead of going to string and parsing.
This should also be handled at the database level. Set a primary key on your username column:
ALTER TABLE UserData ADD CONSTRAINT
PK_UserData PRIMARY KEY CLUSTERED (Username)
If you do it this way, then you don't even have to check for duplicates explicitly, you can just try to create the user and handle the exception if it fails:
try
{
using (var conn = new SqlConnection((ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString)))
{
conn.Open();
#if DOUBLE_CHECK
string CheckUser = "select count(*) from UserData where Username = #Username";
SqlCommand com2 = new SqlCommand(CheckUser, conn);
com2.Parameters.AddWithValue("#Username", UsernameTextBox.Text);
if ((int)com2.ExecuteScalar() > 0)
{
Response.Write("User already exists");
return;
}
#endif
string InsertQuerry = "insert into UserData (Username,Email,Password,Country) values (#Username,#Email,#Password,#Country)";
SqlCommand com = new SqlCommand(InsertQuerry, conn);
com.Parameters.AddWithValue("#Username", UsernameTextBox.Text);
com.Parameters.AddWithValue("#Email", EmailTextBox.Text);
com.Parameters.AddWithValue("#Password", PasswordTextBox.Text);
com.Parameters.AddWithValue("#Country", CountryDropDownList.SelectedItem.ToString());
com.ExecuteNonQuery();
Response.Redirect("Manager.aspx");
}
}
catch (SqlException se)
{
if (se.Errors.OfType<SqlError>().Any(e => e.Number == 2627))
{
Response.Write("User already exists");
}
else
{
Response.Write(se.ToString());
}
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
If you handle the exception this way, the #if DOUBLE_CHECK section is redundant and can be removed. An attempt to add duplicate name will cause a SQL error and exception, and this will detect and handle the "duplicate key" error.
Two unrelated notes on your code:
Response.Redirect() will abort the current thread and your conn.Close() will not be called. Use a using() to ensure it's called.
Storing a password in the database as plain text is a disaster waiting to happen. PLEASE take a look at Best way to store password in database for some ideas about how to do this correctly
That won't return an integer
string CheckUser = "select count(*) from UserData where Username like #Username";
SqlCommand com2 = new SqlCommand(CheckUser, conn2);
com2.Parameters.AddWithValue("#Username", "'%"+ UsernameTextBox.Text +"%'");
int IsMatch = Convert.ToInt32(com2.ExecuteScalar().ToString());
And you don't need to use two different connections.
Just use one and close it in a Finally.
string CheckUser = "select count(*) from UserData where Username = #Username";
SqlCommand com2 = new SqlCommand(CheckUser, conn2);
com2.Parameters.AddWithValue("#Username", UsernameTextBox.Text );
int IsMatch = Convert.ToInt32(com2.ExecuteScalar().ToString());
This returns 0 or 1. This should fix your issue. Looks like you need to return an int type. Or you could change it to bool if you want. Either way, this sql statement should help! :)
select
isnull(convert(bit,(select top 1 case
when username != '' then 1
else 0 end
from UserData
where username like #Username)),0)

Categories