Unable to Make this log in Form in c# / SqlDataReader Issue - c#

I am trying to make a windows Form Application with a login screen,Form3 Will open Form1 if the username and password are correct.
The code is linked to a database
The code is as follows:
private void button1_Click(object sender, EventArgs e)
{
string u_id = textBox1.Text;
string u_pwd = textBox2.Text;
SqlConnection conn = new SqlConnection("Data Source=mmtsql.XXX.XXXXX.ac.uk;Initial Catalog=mmt12-186;User ID=XXXXXX;Password=XXXXXX");
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = ("SELECT * FROM UsersData WHERE User = '" + textBox1.Text + "'");
cmd.Parameters.AddWithValue("un", u_id);
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read() == false)
{
label3.Text = "Invalid Username or Password !";
return;
}
string realpwd = reader.GetString(0);
if (u_pwd == realpwd)
{
Form1 formload = new Form1();
formload.Show();
}
}
Every time I run this code, I get an exception on with the line:
string realpwd = reader.GetString(0);
The exception is:
Invalid attempt to read when no data is present.
The UsersData table has 3 columns, Id, User, Password
Thanks goes to "Alfred Sanz" who answered the question, the problem now is that no error is present but no data is shown, as if the button1_click has no method, the current code is:
private void button1_Click(object sender, EventArgs e)
{
string u_id = textBox1.Text;
string u_pwd = textBox2.Text;
SqlConnection conn = new SqlConnection("Data Source=mmtsql.XX.XXX.ac.uk;Initial Catalog=XXXXXXX ;User ID=XXXX;Password=XXXXX");
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = ("SELECT * FROM UsersData WHERE User = #un");
cmd.Parameters.AddWithValue("#un", u_id);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
if (reader["Password"].ToString() == u_pwd)
{
Form1 formload = new Form1();
formload.Show();
}
else
{
label3.Text = "Invalid Username or Password !";
}
}

you already set the value of USER as '" + textBox1.Text + "'" but you are also setting a value cmd.Parameters.AddWithValue("un", u_id); which really does not exist, change your code into
cmd.CommandText = "SELECT * FROM UsersData WHERE User = #un";
cmd.Parameters.AddWithValue("#un", u_id);
and also you can change the reader part to:
while (reader.Read())
{
if (reader["Password"].ToString() == u_pwd.Text
{
Form1 formload = new Form1();
formload.Show();
}
else
{
label3.Text = "Invalid Username or Password !";
}
}

Related

MySQL connection seems to be only reading first query

I'm working on a C# project and until now I haven't had any difficulties whatsoever, the problem is while coding a simple login form.
Here's the code for it:
MySqlConnection con = new MySqlConnection();
MySqlCommand com = new MySqlCommand();
public LoginForm()
{
InitializeComponent();
con.ConnectionString = #"Data Source=localhost;port=3306;Initial Catalog=databaseName;User id=root;password=''";
}
private void button1_Click(object sender, EventArgs e)
{
con.Open();
com.Connection = con;
com.CommandText = "select * from users";
MySqlDataReader dr = com.ExecuteReader();
if (dr.Read())
{
if (txtBoxUsername.Text.Equals(dr["username"].ToString()) && txtBoxPassword.Text.Equals(dr["password"].ToString()))
{
lblIncorrect.Text = "";
this.Hide();
InjectForm f2 = new InjectForm();
f2.Show();
}
else
{
lblIncorrect.Text = "Incorrect userename or password.";
txtBoxPassword.Text = "";
}
}
con.Close();
}
As you can see, on button click it will open my MySql connection and select everything from the table users. Then check if the username and password entered on the text boxes match with the ones stored on phpMyAdmin.
The problem comes now, if I use the first user, it will sign in correctly and do what it's supposed to do, in the other hand though, if I sign in with my second user, it will throw the "Incorrect username or password." text.
This should all work but it just doesn't.
Any ideas?
For optimal memory consumption and speed up, just fetch the desired record. You will notice a difference in execution speed when the data becomes very large.
change button1_Click to :
private void button1_Click(object sender, EventArgs e)
{
con.Open();
com.Connection = con;
com.CommandText = "select * from users where username = #username and password = #password";
com.Parameters.Add("#username", SqlDbType.VarChar, 50).Value = txtBoxUsername.Text;
com.Parameters.Add("#password", SqlDbType.VarChar, 50).Value = txtBoxPassword.Text;
MySqlDataReader dr = com.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
lblIncorrect.Text = "";
this.Hide();
InjectForm f2 = new InjectForm();
f2.Show();
break;
}
}
else
{
lblIncorrect.Text = "Incorrect userename or password.";
txtBoxPassword.Text = "";
}
con.Close();
}
Note: use while(dr.Read()) to read all rows to scroll through all rows.

How do I actually login user

Im very new to C#, im working on a login system. The program can verify the user information but I dont get how your suppose to log the user in. Beacuse now you get a success message and thats it.
And how do you redirect the user to the rest of the application. This is a native app and all I could find was information about how to redirect in asp.net instad of c#.net.
private void button1_Click(object sender, EventArgs e)
{
string user = textBox1.Text;
string pwd = textBox2.Text;
MySqlConnection conn = new MySqlConnection("server = localhost; user id = root; database = bot");
MySqlDataAdapter sda = new MySqlDataAdapter("select count(*) from license where user = '" + textBox1.Text + "' and pwd = '" + textBox2.Text + "'", conn);
DataTable dt = new DataTable();
sda.Fill(dt);
if (dt.Rows[0][0].ToString() == "1")
{
MessageBox.Show("Successful login!", "info", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Info is not valid", "alter", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
You just need to define an object of the class and the use Show(); after you use this.Hide(); for ASP.NET use Response.Redirect("Dashboard.aspx")
For increasing the security of your login form you should read this to preventing SQL injection attacks: https://www.codeproject.com/Articles/9378/%2FArticles%2F9378%2FSQL-Injection-Attacks-and-Some-Tips-on-How-to-Prev
https://www.mikesdotnetting.com/article/113/preventing-sql-injection-in-asp-net
For the session setting
How to set security on Login Page in asp.net
For encryption :
C# encrypted Login
private void button1_Click(object sender, EventArgs e)
{
string user = textBox1.Text;
string pwd = textBox2.Text;
MySqlConnection conn = new MySqlConnection("server = localhost; user id = root; database = bot");
string query = "Select * from license Where user = '" + textBox1.Text.Trim() + "' and pwd = '" + textBox2.Text.Trim() + "'";
SqlDataAdapter sda = new SqlDataAdapter(query, conn );
DataTable dtbl = new DataTable();
sda.Fill(dtbl);
if (dtbl.Rows.Count == 1)
{ //change the name of the form depend on the form that you need to show.
frmMain objFrmMain = new frmMain();
this.Hide();
objFrmMain.Show();
}
else
{
MessageBox.Show("Check your username and password");
}
}
For ASP.NET
protected void btnLogin_Click(object sender, EventArgs e)
{
using (SqlConnection sqlCon = new SqlConnection("server = localhost; user id = root; database = bot");
{
sqlCon.Open();
string query = "Select * from license Where user = '" + textBox1.Text.Trim() + "' and pwd = '" + textBox2.Text.Trim() + "'";
SqlCommand sqlCmd = new SqlCommand(query, sqlCon);
sqlCmd.Parameters.AddWithValue("#user",textBox1.Text.Trim());
sqlCmd.Parameters.AddWithValue("#pwd", textBox2.Text.Trim());
int count = Convert.ToInt32(sqlCmd.ExecuteScalar());
if (count == 1)
{
Session["user"] = textBox1.Text.Trim();
Response.Redirect("Dashboard.aspx");
}
else { lblErrorMessage.Visible = true; }
}
}
Download the code from here:https://drive.google.com/drive/folders/17KvHSTJvvD5jmcufr35-V8TV67pHL7D8

Check if username is in the database using ASP.Net

I want to check if a username is already in the database. It comes along with my update statement. I have this code and I do not know where to put the select statement:
protected void btn_update_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(conn);
con.Open();
str = "update UserData set Password=#Password where UserName='" + txtUser.Text + "'";
com = new SqlCommand(str, con);
com.Parameters.Add(new SqlParameter("#Password", SqlDbType.VarChar));
com.Parameters["#Password"].Value = BusinessLayer.ShoppingCart.CreateSHAHash(txtPW.Text);
com.ExecuteNonQuery();
con.Close();
Label1.Visible = true;
Label1.Text = "Password changed Successfully!" ;
con.Close();
}
I want something like
"Select Username from Userdata Where Username = txtUser.Text"
You don't need a SELECT here. ExecuteNonQuery() returns the number of rows affected, which means that when it returns 0, there was no user with the given name in the database. If all went well, it should return 1.
Your code is vulnerable to SQL injection and leaks resources. Here's a better version:
protected void btn_update_Click(object sender, EventArgs e)
{
using(var con = new SqlConnection(conn))
{
con.Open();
var commandTest = "update UserData set Password=#Password where UserName=#Username";
using(var com = new SqlCommand(commandTest, con))
{
com.Parameters.AddWithValue("#Username", txtUser.Text);
com.Parameters.AddWithValue("#Password", BusinessLayer.ShoppingCart.CreateSHAHash(txtPW.Text));
if(com.ExecuteNonQuery() == 1)
{
Label1.Visible = true;
Label1.Text = "Password changed Successfully!" ;
}
}
}
}

Object reference not set to an instance of an object. ExecuteScalar()

I am always getting "Object reference not set to an instance of an object". I dont know what i did wrong. I did try to execute the query: "select count(*) from Registration where Username='Myname' and it returned 1;
The code:
protected void Button1_Click(object sender, EventArgs e)
{
DBConnect con = new DBConnect();
string query = "select count(*) from Registration where Username='" + TextBox1.Text + "'";
//Open connection
if (con.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, con.Initialize());
//Create a data reader and Execute the command
int temp = Convert.ToInt32(cmd.ExecuteScalar().ToString());
if (temp == 1)
{
string query1 = "Select Password from Registration where Username='" + TextBox1.Text + "'";
MySqlCommand pass = new MySqlCommand(query1, con.Initialize());
string password = pass.ExecuteScalar().ToString();
if (password == TextBox2.Text)
{
Session["new"] = TextBox1.Text;
Response.Redirect("GreenhouseHomepage.aspx");
}
else
{
Label1.Text = "Invalid Password...!!";
Label1.Visible = true;
}
}
else
{
Label1.Text = "Invalid Username...!!";
Label1.Visible = true;
}
}
//close Connection
con.CloseConnection();
}
The Error:
Give this a try.
//Open connection
if (con.OpenConnection() == true)
{
// Since you know that the connection is open, you can just
// pass the entire conn object
MySqlCommand cmd = new MySqlCommand(query, con);
//Create a data reader and Execute the command
int temp = Convert.ToInt32(cmd.ExecuteScalar());
The COUNT(*) will return 0 if no records are found so you will always get a value from your syntax.

I want to check the username is already exists in my database table or not?

i have registration page and i want to check that username is already exist in database or not in 3 tier architecture.
MyRegistration.cs:
public static int checkusername(string user_txt)
{
int id2 = 0;
string selectstr = "select * from xyz where UserName = '" + user_txt + " ' ";
id2 = DataAccessLayer.ExecuteReader(selectstr);
return id2;
}
and the code behind onclick event of textbox:
protected void txt_username_TextChanged(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txt_username.Text))
{
int id = xyz.checkusername(txt_username.Text.Trim());
if (id > 0)
{
lblStatus.Text = "UserName Already Taken";
}
else
{
lblStatus.Text = "UserName Available";
}
}
}
DataAccessLayer:
public static int ExecuteReader(string Query)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
int id = 0;
SqlCommand cmd = new SqlCommand();
cmd.CommandText = Query;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = con;
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
id++;
}
cmd = null;
reader.Close();
con.Close();
return id;
}
I have edited some of your codes try like below... it will help you...
Text change Event :
protected void txt_username_TextChanged(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txt_username.Text))
{
if (xyz.checkusername(txt_username.Text.Trim()))
{
lblStatus.Text = "UserName Already Taken";
}
else
{
lblStatus.Text = "UserName Available";
}
}
}
Check Username :
public bool CheckUsername(string user_txt)
{
bool Result;
Result = DataAccessLayer.ExecuteReader(user_txt);
return Result;
}
Excute Reader :
public bool ExecuteReader(string user_txt)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
SqlCommand cmd = new SqlCommand("select * from xyz where UserName = #UserID", con);
SqlParameter param = new SqlParameter();
param.ParameterName = "#UserID";
param.Value = user_txt;
cmd.Parameters.Add(param);
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
return true;
else
return false;
}
Usually if the "select query" doesn't find a userName with the parameter user_txt you'll id2 will be end up with the value -1. So the appropriate code would be:
if (id ==-1)
{
lblStatus.Text = "UserName Available";
}
if (id>0)
{
lblStatus.Text = "UserName Already Taken";
}
By the way, your code is highly insecure and your database can be easily attacked using SQL Injection I'd recommend you to understand this issue and add parameters to the query to prevent it. C# has its ways to implement this. Don't try to fix the access to the database, just start from scrath keeping in mind SQL Injection.
As others have mentioned, this approach has potentially serious security issues.
However, your problem may lie here user_txt + " ' ". The spaces around the second ', specifically the one before it may lead to the usernames not matching as expected.

Categories

Resources