In this database table (administration), there are 4 attributes (email, name, password and mobile phone). I need that inside the if I can use each one of them but I don't know how I can access them.
How can I do this?
private void button_login_Click(object sender, EventArgs e)
{
String username, user_password;
username = txt_username.Text;
user_password = txt_password.Text;
try
{
String query = "SELECT * FROM administracao WHERE email = '"+txt_username.Text+"' AND password = '"+txt_password.Text+"'";
SqlDataAdapter sda = new SqlDataAdapter(query, conn);
DataTable dtable = new DataTable();
sda.Fill(dtable);
if (dtable.Rows.Count > 0)
{
// username = txt_username.Text;
// user_password = txt_password.Text;
/* Menuform form2 = new Menuform();
form2.Show();
this.Hide();*/
}
else
{
MessageBox.Show("Invalid Login details", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
txt_username.Clear();
txt_password.Clear();
txt_username.Focus();
}
}
catch
{
MessageBox.Show("Error");
}
finally
{
conn.Close();
}
}
For communication with database I would strongly recommend Entity Framework.
In your case you can use SqlDataReader to get output data from sql query
Code Example:
public void GetData()
{
var query = "your query";
var connectionString = "your connection string";
using (var connection = new SqlConnection(connectionString))
{
var command = new SqlCommand(query, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
// Iterate all selected rows
while (reader.Read())
{
int value1 = (int)reader["Int column name"];
string value2 = (string)reader["String column name"];
}
}
finally
{
reader.Close();
}
}
}
NOTE:
In real project NEVER store passwords as plaintext. How to do it properly
As people already mentioned in the comments, when you decide to execute query directly from the code NEVER combine query like you did, because of SQL Injection. Use parametrized SqlCommands. How to do it
Related
Im trying to validate the password from my database that has been hash and salted. I Created an column in my user table username, hash and salt. Now i want to know i can i access the other column value using datareader.
I tried this method but i got an red line. also this is my failed attempt
public static bool VerifyPassword(string enteredPassword, string storedHash, string storedSalt)
{
var saltBytes = Convert.FromBase64String(storedSalt);
var rfc2898DeriveBytes = new Rfc2898DeriveBytes(enteredPassword, saltBytes, 10000);
return Convert.ToBase64String(rfc2898DeriveBytes.GetBytes(256)) == storedHash;
}
private void bunifuFlatButton1_Click(object sender, EventArgs e)
{
string userhash;
string usersalt;
MySqlConnection mysqlCon = new MySqlConnection(connectionString);
MySqlCommand cmd = new MySqlCommand("SELECT * FROM login.info WHERE username = #user", mysqlCon);
MySqlDataReader rd;
rd = cmd.ExecuteReader();
cmd.Parameters.Add("#user", MySqlDbType.VarChar).Value = username.Text;
mysqlCon.Open();
while (rd.Read())
{
userhash = rd.GetString("hash");
usersalt = rd.GetString("salt");
bool isPasswordMatched = VerifyPassword(textpass.Text, userhash.Hash, usersalt.Salt);
// i got redline error in here. i only follow instruction.. link below
if (isPasswordMatched)
{
//Login Successfull
}
else
{
//Login Failed
}
}
}
by the way, i only follow this instruction from this thread. How to validate salted and hashed password in c#
Here is another way of writing your code, not really an answer, but...not perfect mind, but at least it will dispose of the objects and also call them in the correct order. Please read upon on IDisposable and Sql Injection.
private void bunifuFlatButton1_Click(object sender, EventArgs e)
{
using (MySqlConnection mysqlCon = new MySqlConnection(connectionString))
{
// Use a named list of fields please. And cleanse the text.
using (MySqlCommand cmd = new MySqlCommand("SELECT * FROM login.info WHERE username = #user", mysqlCon))
{
cmd.Parameters.Add("#user", MySqlDbType.VarChar).Value = username.Text; // Let's hope user name is not Jimmy DropTables!!
mysqlCon.Open();
using (MySqlDataReader rd = cmd.ExecuteReader())
{
while (rd.Read())
{
string userhash = rd.GetString("hash");
string usersalt = rd.GetString("salt");
bool isPasswordMatched = VerifyPassword(textpass.Text, userhash, usersalt);
// Note that we are passing in strings, not props of an unknown object
if (isPasswordMatched)
{
//Login Successfull
}
else
{
//Login Failed
}
}
}
mysqlCon.Close();
}
}
}
I need to create a login that displays user data after login in a gridview / datatable
I'm able to display the username / password but not the user ID that's needed.
I've also tried creating a class where the values gets stored after login
private bool DataValidation(string user, string pass)
{
using (MySqlConnection conn = new MySqlConnection(connectionString))
using (MySqlCommand cmd = new MySqlCommand("SELECT * "+
"FROM member " +
"WHERE username=#user AND password=#pass;", conn))
{
cmd.Parameters.AddWithValue("#user", user);
cmd.Parameters.AddWithValue("#pass", pass);
cmd.Connection = conn;
cmd.Connection.Open();
MySqlDataReader login = cmd.ExecuteReader();
List<Connect> connectList = new List<Connect>();
while (login.Read())
{
Connect connect = new Connect();
connect.username = login.GetString(0);
connect.password = login.GetString(1);
connect.userID = login.GetString(4);
connectList.Add(connect);
}
if(connectList.Count > 0)
{
return true;
}
else
{
return false;
}
}
I'm mostly not sure how to store or display the values after they have been queried
Based on our conversation in the comments, let's focus on this code:
MySqlDataReader login = cmd.ExecuteReader();
if (login.Read())
{
conn.Close();
return true;
}
else
{
conn.Close();
return false;
}
The only thing we are doing here is finding out if login contains any rows. But we are not doing anything with those rows.
Let's try something like this instead:
MySqlDataReader login = cmd.ExecuteReader();
while (login.Read())
{
var something1 = login.GetString(0); // this will get the value of the first column
var something2 = login.GetString(1); // this will get the value of the second column
}
Or, if you are adding the results to an object:
MySqlDataReader login = cmd.ExecuteReader();
List<MyObject> myObjectList = new List<MyObject>;
while (login.Read())
{
MyObject myObject = new MyObject;
myObject.something1 = login.GetString(0); // this will get the value of the first column
myObject.something2 = login.GetString(1); // this will get the value of the first column
myObjectList.Add(myObject);
}
if (myObjectList.Count > 0)
{
return true;
}
else
{
return false;
}
You will need to adjust to meet your needs, but hopefully, this will get you there.
More info here: SqlDataReader.Read Method
I tried to make an e-contact app with C# on Visual Studio 2019 connected to a Miscrosoft SQL database (local) following a youtube tutorial.
The app is not complete yet, anyway the btnAdd should work, but it doesn't add the user and the return of the method (Insert).
It always returns false - Can anyone help me?
private void BntAdd_Click(object sender, EventArgs e) {
//Get the value from the imput fields
c.Nome = txtBoxName.Text;
c.Cognome = txtBoxSurname.Text;
c.Telefono1= txtBoxPhone1.Text;
c.Telefono = txtBoxPhone.Text;
c.Email = txtBoxEmail.Text;
//Inserting Data into Database uing the method we created is previous episode
bool success = c.Insert(c);
if (success == true)
{
//Successfully Inserted
MessageBox.Show("New contact added!");
//Call the clear Method Here
Clear();
}
else
{
//Failed to add Contact
MessageBox.Show("ERROR!)");
}
//load Data on Data GRidview
DataTable dt = c.Select();
dgvRubrica.DataSource = dt;
}
public void Clear()
{
txtBoxName.Text = "";
txtBoxSurname.Text = "";
txtBoxPhone1.Text = "";
txtBoxPhone.Text = "";
txtBoxEmail.Text = "";
}
public bool Insert (rubricaClass c) {
bool isSuccess = false;
SqlConnection conn = new SqlConnection(myconnstrng);
try
{
string sql = "INSERT INTO tbl_Rubrica (Nome, Cognome, Telefono1, Telefono, Email) VALUES (#Nome, #Cognome, #Telefono1, #Telefono, #Email)";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#Nome", c.Nome);
cmd.Parameters.AddWithValue("#Cognome", c.Cognome);
cmd.Parameters.AddWithValue("#Telefono1", c.Telefono1);
cmd.Parameters.AddWithValue("#Telefono", c.Telefono);
cmd.Parameters.AddWithValue("#Email", c.Email);
conn.Open();
int rows = cmd.ExecuteNonQuery();
if (rows > 0)
{
isSuccess = true;
}
else
{
isSuccess = false;
}
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
return isSuccess;
}
It doesn't give any errors, it work but when i type the ata into txtBoxes and then i press the add button it says Error (message box inserte in the else)
Step 1 is to remove the catch-all exception handling from the Insert method. Most of the ADO.NET database classes implement IDisposable, so you just need a using(...) block to make sure the command is disposed automatically (which will also close and dispose the connection instance):
public bool Insert (rubricaClass c)
{
bool isSuccess = false;
SqlConnection conn = new SqlConnection(myconnstrng);
string sql = "INSERT INTO tbl_Rubrica (Nome, Cognome, Telefono1, Telefono, Email) VALUES (#Nome, #Cognome, #Telefono1, #Telefono, #Email)";
using(SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("#Nome", c.Nome);
cmd.Parameters.AddWithValue("#Cognome", c.Cognome);
cmd.Parameters.AddWithValue("#Telefono1", c.Telefono1);
cmd.Parameters.AddWithValue("#Telefono", c.Telefono);
cmd.Parameters.AddWithValue("#Email", c.Email);
conn.Open();
int rows = cmd.ExecuteNonQuery();
if (rows > 0)
{
isSuccess = true;
}
else
{
isSuccess = false;
}
}
return isSuccess;
}
Once that's squared away, Step 2 is to move your exception handling into the application. I don't recommend this "catch everything"-style code, but it works for now, I suppose:
private void BntAdd_Click(object sender, EventArgs e)
{
//Get the value from the imput fields
c.Nome = txtBoxName.Text;
c.Cognome = txtBoxSurname.Text;
c.Telefono1= txtBoxPhone1.Text;
c.Telefono = txtBoxPhone.Text;
c.Email = txtBoxEmail.Text;
try
{
//Inserting Data into Database uing the method we created is previous episode
bool success = c.Insert(c);
if (success == true)
{
//Successfully Inserted
MessageBox.Show("New contact added!");
//Call the clear Method Here
Clear();
}
else
{
//Failed to add Contact
MessageBox.Show("ERROR!)");
}
//load Data on Data GRidview
DataTable dt = c.Select();
dgvRubrica.DataSource = dt;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
This will likely tell you that you either have an error in your SQL syntax, or that the command itself could not be run (i.e. the connection string is invalid or the server can't be reached).
I have a database created in a server and I added a row by MySql query browser for testing. This row is visible either with PhpMyAdmin or MySql query browser.
But when I want to reach this table within my program it says me there is no rows (reader.HasRows = false)
cs is the connection string in PublicVariables class
Here is the code
public static int checkuser(string myuser, string mypass)
{
try
{
using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs))
{
string MypassMd5 = MakeMD5(mypass);
conn.Open();
if (conn == null)
Environment.Exit(0);
using (MySqlCommand cmd =
new MySqlCommand("SELECT username, password " + "FROM Users WHERE username = 'myuser'" ,conn))
{
using (MySqlDataReader reader = cmd.ExecuteReader())
{
//DateTime mytime = DateTime.Now ;
if (reader.HasRows)
{
if (Convert.ToString(reader["password"]) != MypassMd5)
{
reader.Close();
conn.Close();
return -1;
}
else
{
PublicVariables.UserId = Convert.ToString(reader["username"]);
PublicVariables.UserDegre = Convert.ToInt16(reader["userdegre"]);
conn.Close();
reader.Close();
return 1;
}
}
else
{
reader.Close();
conn.Close();
return 2;
}
}
}
}
}
catch (MySqlException ex)
{
MessageBox.Show(ex.ToString());
}
return 0;
}
What's wrong in my code?
Well the primary error is in your command string , myuser is a variable and you cannot pass its value putting the variable name inside quotes.
new MySqlCommand("SELECT username, password FROM Users WHERE username = 'myuser'" ,conn)
instead this line should be converted to use a parameterized query
string commandText = "SELECT username, password, userdegre FROM Users WHERE username = #uname";
using (MySqlCommand cmd = new MySqlCommand(commandText ,conn)
{
cmd.Parameters.AddWithValue("#uname", myuser);
....
Looking at your code you have another error after this. You try to read the field userdegre, but this field is not retrieved by your query, so you need to add it to the list of retrieved fields.
But the only field you really need to know is userdegre because you already know the username and the password, so you could remove the datareader and use ExecuteScalar and pass the username and the password as parameters for the WHERE clause. If you get anything in return then you are sure that your user is authenticated by the database.
string commandText = "SELECT userdegre FROM Users WHERE username = #uname AND Password =#pwd";
using(MySqlCommand cmd = new MySqlCommand( commandText ,conn))
{
cmd.Parameters.AddWithValue("#uname", myuser);
cmd.Parameters.AddWithValue("#pwd", MypassMd5);
var result = cmd.ExecuteScalar();
if(result != null)
{
PublicVariables.UserId = myuser;
PublicVariables.UserDegre = result.ToString();
}
}
Don't check reader.HasRows. You need to call reader.Read(), and check the result of that.
Also, some side issues:
MD5 is incredibly weak for a password hash. Really. Just don't use it for that. Look into bcrypt as a much better alternative. Better still if you're not writing authentication code yourself at all. Look for a library for help to get this stuff right... it's just so easy to write authentication code that seems to work, passes all your tests, but has a subtle flaw that gets you hacked a few months down the road.
No need to call conn.Close(). That's what your using blocks are for. They will handle this for you.
I'd remove the try/catch as well. Since you're already returning error conditions to the calling code, I'd leave that as the place where errors are processed, such that your try/catch should go at that level.
You're looking for userdegre in the results that was not in the select list.
Parameterized queries are your friend.
Put it all together you and you end up with this:
public static int checkuser(string myuser, string mypass)
{
string passHash = BCrypt(mypass); //Need to get bcyrpt library and make the function
using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs))
using (MySqlCommand cmd =
new MySqlCommand("SELECT username, password, userdegre FROM Users WHERE username = #user" ,conn))
{
cmd.Parameters.Add("#user", SqlDbType.NVarChar, 20).Value = myuser;
conn.Open();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (!reader.Read()) return 2;
if (Convert.ToString(reader["password"]) != MypassMd5) return -1;
PublicVariables.UserId = Convert.ToString(reader["username"]);
PublicVariables.UserDegre = Convert.ToInt16(reader["userdegre"]);
return 1;
}
}
}
I would try something like this new MySqlCommand("SELECT username, password, userdegre " + "FROM Users WHERE username = 'myuser'" ,conn))
adding userdegre the column name in your select statement.
Finally for c# 2008 net 3.5 WORKING COPY of this after the help of #Joel and # Steve is as this:
public static int usertrue(string myuser, string mypass)
{
try
{
using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs))
{
string MypassMd5 = MakeMD5(mypass);
using (MySqlCommand cmd =
new MySqlCommand("SELECT username, password ,userdegre FROM Users WHERE username = #user",conn))
{
cmd.Parameters.Add("#user", MySqlDbType.VarChar, 15).Value = myuser;
conn.Open();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (!reader.Read()) return 2;
if (Convert.ToString(reader["password"]) != MypassMd5) return -1; {
PublicVariables.UserId = Convert.ToString(reader["username"]);
PublicVariables.UserDegre = Convert.ToInt16(reader["userdegre"]);
return 1;
}
}
}
}
}
i have a php code.here is the code,i gonna to translate it to .NET but in some point i'm getting some trouble.
function processInput($conn, $MessageArray, $mobilenumber, $date, $odd)
{
$strSQLUSER="SELECT * FROM tbl_tiduser WHERE username='".addslashes($MessageArray[0])."' AND stat!='1' AND stat!='4'";
$result_user=odbc_exec($conn,$strSQLUSER) or die("Could not connect to database");
here is the converted .NET code
public class ProcessInput
{
private string msg_arr;
private string MooseSeenInput(string MobileNo,string Date,string odd,params Array[] msg_arr)
{
SqlCommand com = new SqlCommand("SELECT * FROM tbl_tiduser WHERE username=#username AND stat!='1' AND stat!='4'", mycon);
com.Parameters.AddWithValue("#username",username);
using (SqlDataReader reader = com.ExecuteReader())
// whats the next part need to come here ???
}
this is incomplete.i'm not going to compile it....
private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlCommand command =
new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Call Read before accessing data.
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
// Call Close when done reading.
reader.Close();
}
}
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.aspx
I would use something like this to get the column(s) you're after:
string username = null;
using (SqlDataReader reader = com.ExecuteReader()) {
if (reader.read()) {
username = (string)reader["mydbcolumnname"];
}
reader.Close();
}
Note that if you want to pull all the result rows (as opposed to stepping through them) then you'd normally use a SqlDataAdapter to fill a DataSet (instead of the reader), eg:
string username;
using (SqlDataAdapter adapter = new SqlDataAdapter(com))
{
using (DataSet ds)
{
adapter.Fill(ds);
username = (string)ds.Tables[0].Rows[0]["mycolumnname"];
}
}
I'm all for easy; I would write a class that mirrors the record I'm reading, i.e.
public class User {
public int Id {get;set;}
public string Name {get;set;}
}
and use "dapper":
var user = myCon.Query<User>(
"SELECT * FROM tbl_tiduser WHERE username=#username AND stat not in ('1','4')",
new {username}).SingleOrDefault();
if(user == null) { /* not found, presumably throw an exception */ }
string name = user.Name; // etc
Then you don't need to mess with commands, readers, parameters etc (see how the username is being made into a db parameter cleanly?).