How do I fix the IF statement so when the user tries to sign up using an already existing username. Currently my program will not accept the data entered if the username is already existing, but it still proceeds to the next page (even though the data is not saved in the database). What I need to know is how to eliminate the problem so when the user does enter a "username" that exists it'll just give the message box for the error and not move to the next page.
Thanks!
private void btnSignupNew_Click(object sender, EventArgs e)
{
if (txtUsername.Text == "")
{
errorUsername.SetError(txtUsername, "Enter A Username");
}
else if (txtPassword.Text == "")
{
errorPassword.SetError(txtPassword, "Enter A Valid Password");
}
else
{
using (SqlConnection con = new SqlConnection("Data Source=etc"))
{
con.Open();
bool exists = false;
// create a command to check if the username exists
using (SqlCommand cmd = new SqlCommand("select count(*) from [User] where UserName = #UserName", con))
{
cmd.Parameters.AddWithValue("UserName", txtUsername.Text);
exists = (int)cmd.ExecuteScalar() > 0;
}
// if exists, show a message error
if (exists)
{
MessageBox.Show("Username: " + txtUsername.Text + " already Exists");
//errorPassword.SetError(txtUsername, "This username has been using by another user.");
}
else
{
// does not exists, so, persist the user
using (SqlCommand cmd = new SqlCommand("INSERT INTO [User] values (#Forename, #Surname, #Username, #Password)", con))
{
cmd.Parameters.AddWithValue("Forename", txtForename.Text);
cmd.Parameters.AddWithValue("Surname", txtSurname.Text);
cmd.Parameters.AddWithValue("UserName", txtUsername.Text);
cmd.Parameters.AddWithValue("Password", txtPassword.Text);
cmd.ExecuteNonQuery();
}
}
con.Close();
MessageBox.Show("Sucessfully Signed Up");
Form1 signin = new Form1();
signin.Show();
this.Close();
}
}
}
}
Your code is always going to close the form and launch the login form, regardless of whether the username already existed or not, because the logic to do the login form is executed after your test for uniqueness. It should only happen when the test for uniqueness suceeds.
Change your logic to look like this:
// if exists, show a message error
if (exists)
{
MessageBox.Show("Username: " + txtUsername.Text + " already Exists");
//errorPassword.SetError(txtUsername, "This username has been using by another user.");
}
else
{
// does not exists, so, persist the user
using (SqlCommand cmd = new SqlCommand("INSERT INTO [User] values (#Forename, #Surname, #Username, #Password)", con))
{
cmd.Parameters.AddWithValue("#Forename", txtForename.Text);
cmd.Parameters.AddWithValue("#Surname", txtSurname.Text);
cmd.Parameters.AddWithValue("#UserName", txtUsername.Text);
cmd.Parameters.AddWithValue("#Password", txtPassword.Text);
cmd.ExecuteNonQuery();
}
MessageBox.Show("Sucessfully Signed Up");
Form1 signin = new Form1();
signin.Show();
this.Close();
}
con.Close();
Change your Parameters to look like the following as well
I would also recommend adding some sort of Validation if necessary to the edit boxes in case someone adds improper values to prevent from any SQL Injectection personally I would create Property values for the Edit boxes and pass in the Property Value(s). just a suggestion
First problem in your code that stood out to me was the following line
cmd.Parameters.AddWithValue("UserName", txtUsername.Text);
should be
cmd.Parameters.AddWithValue("#UserName", txtUsername.Text);
// if exists, show a message error
if (exists)
{
MessageBox.Show("Username: " + txtUsername.Text + " already Exists");
//errorPassword.SetError(txtUsername, "This username has been using by another user.");
}
else
{
// does not exists, so, persist the user
using (SqlCommand cmd = new SqlCommand("INSERT INTO [User] values (#Forename, #Surname, #Username, #Password)", con))
{
cmd.Parameters.AddWithValue("#Forename", txtForename.Text);
cmd.Parameters.AddWithValue("#Surname", txtSurname.Text);
cmd.Parameters.AddWithValue("#UserName", txtUsername.Text);
cmd.Parameters.AddWithValue("#Password", txtPassword.Text);
cmd.ExecuteNonQuery();
}
MessageBox.Show("Sucessfully Signed Up");
Form1 signin = new Form1();
signin.Show();
this.Close();
}
con.Close();
Related
Pro devs, I have a problem with my code in c#.net and I knew you can help me. the problem is in the Login code, every time I entered a value that is existed in the database it says "Username or password is incorrect" and when I entered a value that does not exist in the DB it says again "Username or password is incorrect" please help me thank you.
I have tried to edit the query and remove the open close in the asterisk but the output is the same.
public void checkLoginAccount()
{
frmMain frmLogin = new frmMain();
con = new MySqlConnection();
con.ConnectionString = "server=localhost;userid=root;password=alpine;port=3305;database=pos_db;pooling=false;SslMode=none";
con.Open();
string qry = "SELECT COUNT(*) FROM pos_db.tbllogin WHERE BINARY Username=#user AND BINARY Password=#pass";
MySqlCommand cmd = new MySqlCommand(qry, con);
cmd.Parameters.AddWithValue("#user", frmLogin.txtUsername.Text);
cmd.Parameters.AddWithValue("#pass", frmLogin.txtPassword.Text);
int count = Convert.ToInt32(cmd.ExecuteScalar());
if (count != 0)
{
MessageBox.Show("Welcome");
}
else
{
MessageBox.Show("Either username or password is incorrect!");
return;
}
con.Close();
con.Dispose();
}
You are creating a new form instance in your function:
frmMain frmLogin = new frmMain();
So the username and password are always empty here:
cmd.Parameters.AddWithValue("#user", frmLogin.txtUsername.Text);
cmd.Parameters.AddWithValue("#pass", frmLogin.txtPassword.Text);
You need to use the right instance of your form.
Try reading the rows and count in the code. That should look something like this:
string qry = "SELECT Username FROM pos_db.tbllogin WHERE BINARY Username=#user AND BINARY Password=#pass";
MySqlCommand cmd = new MySqlCommand(qry, con);
cmd.Parameters.AddWithValue("#user", frmLogin.txtUsername.Text);
cmd.Parameters.AddWithValue("#pass", frmLogin.txtPassword.Text);
mySqlDataReader reader = cmd.ExecuteReader();
if(reader.Read() == true)
{
MessageBox.Show("Welcome");
}
else
{
MessageBox.Show("Either username or password is incorrect!");
return;
}
I started to learn ASP.NET. I create a register system, and when I try to check if the username or email already exists in the database, it's not checked and creates the user even when you have it already.
try
{
conn.Open();
bool exists = false;
string checkuser = "SELECT count(*) FROM accounts WHERE username='" + username.Text + "'";
SqlCommand cmd2 = new SqlCommand(checkuser, conn);
cmd2.Parameters.AddWithValue("username", username.Text);
exists = (int)cmd2.ExecuteScalar() > 0;
if (exists)
{
Response.Write("User already exists");
}
string command = "INSERT INTO accounts (username, email, password) VALUES (#username, #email, #password)";
SqlCommand cmd = new SqlCommand(command, conn);
cmd.Parameters.AddWithValue("#username", username.Text);
cmd.Parameters.AddWithValue("#email", email.Text);
cmd.Parameters.AddWithValue("#password", password.Text);
cmd.ExecuteNonQuery();
}
catch(Exception)
{
label_msg.Visible = true;
label_msg.Text = "Something went wrong....";
throw;
}
finally
{
Response.Redirect("/layout.aspx");
conn.Close();
}
Thanks !
string checkuser = "if exists (select 1 from accounts where username=#username) select 1 else select 0 end";
SqlCommand cmd2 = new SqlCommand(checkuser, conn);
cmd2.Parameters.AddWithValue("#username", username.Text);
bool exists = (int)cmd2.ExecuteScalar() > 0;
Having SQL Server check for the existence of matches will stop at the first match instead of potentially returning a set of matches and then it is simply returning a value accordingly. This will minimize data transferred between the server and your software plus avoid performing a count when we really just care if there are any matches.
whenever you want to find TRUE/FALSE value or counting the no records always use COUNT(1).
bool exists = false;
string checkuser = "SELECT count(*) FROM accounts WHERE username=#username;";
SqlCommand cmd2 = new SqlCommand(checkuser, conn);
cmd2.Parameters.AddWithValue("#username", username.Text);
object result = cmd2.ExecuteScalar();
if (result != null)
exists = (Convert.ToInt32(result) == 1) ? true : exists;
if (exists)
{
Response.Write("User already exists");
}
Check if user Exist already
int exists = 0;
string checkuser = "SELECT count(*) FROM accounts WHERE username='" +username.Text + "'";
SqlCommand cmd2 = new SqlCommand(checkuser, conn);
cmd2.Parameters.AddWithValue("username", username.Text);
exists = (int)cmd2.ExecuteScalar();
if (exists>0)
{
Response.Write("User already exists");
}
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.
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)
I want to create a Registration and Log In form on Visual Studio 2010 (with Visual C#).
I have created Service-Based Database and one table. I can insert data into the table (at the registration form), but I cannot figure out how to log in the user.
I have a very simple Log In Form (just fields for username and password) and a 'Log In' Button. I do not really know how to check if the password and the username (that exist in my database) match. Here is what I have so far:
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text != "" & textBox2.Text != "")
{
cn.Open(); // cn is the Sqlconnection
cmd.Parameters.AddWithValue("#Username", textBox1.Text); // cmd is SqlCommand
cmd.Parameters.AddWithValue("#Password", textBox2.Text);
if (cmd.CommandText == "SELECT * FROM Table1 WHERE username = #Username AND password = #Password")
{
MessageBox.Show("Loggen In!");
this.Close();
}
cn.Close();
}
}
You need to Execute the query to know if the information exists in the database
if (textBox1.Text != "" & textBox2.Text != "")
{
string queryText = #"SELECT Count(*) FROM Table1
WHERE username = #Username AND password = #Password";
using(SqlConnection cn = new SqlConnection("your_connection_string"))
using(SqlCommand cmd = new SqlCommand(queryText, cn))
{
cn.Open();
cmd.Parameters.AddWithValue("#Username", textBox1.Text);
cmd.Parameters.AddWithValue("#Password", textBox2.Text);
int result = (int)cmd.ExecuteScalar();
if (result > 0)
MessageBox.Show("Loggen In!");
else
MessageBox.Show("User Not Found!");
}
}
I have also changed something in your code.
Changed the query text to return just the count of the users with the
specific username and account and be able to use ExecuteScalar
Enclosed the creation of the SqlConnection and SqlCommand in a using
statement to be sure to dispose these objects at the end of the
operation
I also recommend to change the the way in which you store the password.
Store, in the password field, an hash not the clear password. Then pass to the database the same hash and compare this against the content of the database field.
In this way, the password is known only to your user, not by you or by any passersby that looks at the database table
SqlConnection con = new SqlConnection("connection_string");
SqlCommand cmd = new SqlCommand("select Count(*) from [dbo].[Table] where uname=#uname and password=#password");
cmd.Connection = con;
con.Open();
cmd.Parameters.AddWithValue("#uname", uname.Text);
cmd.Parameters.AddWithValue("#password", password.Text);
int Result=(int)cmd.ExecuteScalar();
if (Result > 0)
{
Response.Redirect("welcome.aspx");
}
else
{
Response.Redirect("register.aspx");
}