i am using C# and i need to develop a check system for a mysql user and password.
So far what ive come up with is this and the error i get is that it is the wrong syntax...
public bool VerifyUser(string username, string password)
{
string returnValue = "";
string Query = "SELECT Pass FROM Base_Character WHERE User='" + username + "'";
MySqlCommand verifyUser = new MySqlCommand(Query, this.sqlConn);
try
{
verifyUser.ExecuteNonQuery();
MySqlDataReader myReader = verifyUser.ExecuteReader();
while (myReader.Read() != false)
{
returnValue = myReader.GetString(0);
}
myReader.Close();
}
catch (Exception excp)
{
Exception myExcp = new Exception("Could not verify user. Error: " +
excp.Message, excp);
throw (myExcp);
}
if (returnValue == password)
{
return false;
}
else
{
return true;
}
}
ExecuteNonQuery is for DELETE, INSERT and UPDATE. Whenever you want data returned as rows from database, use ExecuteReader
Your query should check the username and password together, if they exist in one record then the row is returned else nothing is returned.
You still need more to learn about coding/database programming using .Net
public bool VerifyUser(string username, string password)
{
bool returnValue = false;
string Query = "SELECT 1 FROM Base_Character WHERE User='" + username + "' AND pass='"+password+"'";
try
{
MySqlCommand command = new MySqlCommand(Query, this.sqlConn);
MySqlDataReader myReader = command.ExecuteReader();
if(myReader.Read())
{
returnValue = true;
}
myReader.Close();
}
catch (Exception excp)
{
throw;
}
return returnValue;
}
You should probably not throw a custom exception since you are using boolean
if(VerifyUser("user123", "******"))
{
//Congratulations
}
else
{
//Unable to log you in
}
Thanks guys, but this calls for a custom encryption that mysql cant hold or process, my main error was ovrlooking the executenonquery(), so i had to make the code like this:
if (AuthorizeTools.Encrypt.Password(Database.getPassword) != Password) //Password is already encrypted
Then set the mysql function to:
public string getPassword(string username)
{
string returnValue = "";
string Query = "SELECT Pass FROM Base_Character where (User=" +
"'" + username + "') LIMIT 1";
MySqlCommand checkUser = new MySqlCommand(Query, this.sqlConn);
try
{
checkUser.ExecuteNonQuery();
MySqlDataReader myReader = checkUser.ExecuteReader();
while (myReader.Read() != false)
{
returnValue = myReader.GetString(0);
}
myReader.Close();
}
catch (Exception excp)
{
Exception myExcp = new Exception("Could not grab password: " +
excp.Message, excp);
throw (myExcp);
}
return (returnValue);
}
Related
So I know this is a often asked question but I want to check if the username is already taken in the database using c#. I tried this:
MySqlCommand cmd2 = new MySqlCommand("SELECT * FROM tablename WHERE(name = '" + tb1.Text + "');");
cmd2.Connection = connect;
connect.Open();
string unt = "";
try
{
MySqlDataReader dr;
dr = cmd.ExecuteReader();
while (dr.Read())
{
unt= dr.GetString("name");
}
dr.Close();
}
catch (Exception ex)
{
errorbox.Content = ex.Message;
}
finally
{
connect.Close();
}
if(unt == "" || unt == "0") {
continuel = false;
tb2.Text = "User " +tb1.Text+ " doesn't exist!";
Popup1.IsOpen = true;
}
Its a WPF project and the variable 'continuel' is set to true by default. The code doesn't recognize if a user doesn't exist.
First off your code is vulnerable to sql inject, you should never concatenate values into a query. secondly you can do a count and execute a scalar. Not I stripped down your code a little you'll have to add error handling back.
bool userExists = false;
private String sql = "SELECT COUNT(*) FROM tableName WHERE name = #usernameparam;";
MySqlCommand m = new MySqlCommand(sql);
m.Parameters.AddWithValue("#usernameparam", tb1.Text.Trim());
int userCount = Convert.ToInt32(m.ExecuteScalar());
if(userCount>0)
{
userExists = true;
}
//use userExists variable to evaluate if user exists
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 want to create a database if it does not exist. I am trying to do it with this code but it has errors and I get this message
enter image description here
Please help.
Code:
if(dbex == false)
{
string str;
SqlConnection mycon = new SqlConnection("Server=.\\sqlexpress;initial catalog=Masalehforoshi;Integrated security=SSPI;database=master");
str = "CREATE DATABASE [Masalehforoshi] CONTAINMENT = NONE ON PRIMARY" +
"(NAME=N'Masalehforoshi'," +
#"FILENAME=N'C:\data\Masalehforoshi.mdf' " +
",SIZE=3072KB,MAXSIZE=UNLIMITED,FILEGROWTH=1024KB)" +
"LOG ON (NAME=N'Masalehforoshi_log.', " +
#"FILENAME=N'C:\Masalehforoshi_log.ldf' "+
",SIZE=1024KB,MAXSIZE=2048GB,FILEGROWTH=10%)";
SqlCommand mycommand = new SqlCommand(str, mycon);
try
{
mycommand.Connection.Open();
mycommand.ExecuteNonQuery();
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString(), "myprogram", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
if(mycon.State == ConnectionState.Open)
{
mycon.Close();
}
}
}
My Create Database function
public bool CreateDatabase(SqlConnection connection, string txtDatabase)
{
String CreateDatabase;
string appPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
GrantAccess(appPath); //Need to assign the permission for current application to allow create database on server (if you are in domain).
bool IsExits = CheckDatabaseExists(connection, txtDatabase); //Check database exists in sql server.
if (!IsExits)
{
CreateDatabase = "CREATE DATABASE " + txtDatabase + " ; ";
SqlCommand command = new SqlCommand(CreateDatabase, connection);
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch (System.Exception ex)
{
MessageBox.Show("Please Check Server and Database name.Server and Database name are incorrect .", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
return false;
}
finally
{
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
}
return true;
}
return false;
}
My GrantAccess function to allow permission for current app
public static bool GrantAccess(string fullPath)
{
DirectoryInfo info = new DirectoryInfo(fullPath);
WindowsIdentity self = System.Security.Principal.WindowsIdentity.GetCurrent();
DirectorySecurity ds = info.GetAccessControl();
ds.AddAccessRule(new FileSystemAccessRule(self.Name,
FileSystemRights.FullControl,
InheritanceFlags.ObjectInherit |
InheritanceFlags.ContainerInherit,
PropagationFlags.None,
AccessControlType.Allow));
info.SetAccessControl(ds);
return true;
}
Check Database exists function below
public static bool CheckDatabaseExists(SqlConnection tmpConn, string databaseName)
{
string sqlCreateDBQuery;
bool result = false;
try
{
sqlCreateDBQuery = string.Format("SELECT database_id FROM sys.databases WHERE Name = '{0}'", databaseName);
using (SqlCommand sqlCmd = new SqlCommand(sqlCreateDBQuery, tmpConn))
{
tmpConn.Open();
object resultObj = sqlCmd.ExecuteScalar();
int databaseID = 0;
if (resultObj != null)
{
int.TryParse(resultObj.ToString(), out databaseID);
}
tmpConn.Close();
result = (databaseID > 0);
}
}
catch (Exception)
{
result = false;
}
return result;
}
Based on this support article https://support.microsoft.com/en-us/kb/307283 which has a similar database creation script I suggest removing the "CONTAINMENT = NONE" section.
By default, all SQL Server 2012 and later databases have a containment set to NONE.(https://msdn.microsoft.com/en-us/library/ff929071.aspx), so it probably isn't necessary for your script
It is possible that ado .net doesn't support that tsql command, there is a whole other SQL Server Management Objects library available for messing with advance database and schema scripts https://msdn.microsoft.com/en-us/library/ms162169.aspx . I've used it to create missing databases with table definitions etc during application startup.
To simplify things, here is an even shorter solution.
public void CreateDatabaseIfNotExists(string connectionString, string dbName)
{
SqlCommand cmd = null;
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (cmd = new SqlCommand($"If(db_id(N'{dbName}') IS NULL) CREATE DATABASE [{dbName}]", connection))
{
cmd.ExecuteNonQuery();
}
}
}
My Class
public string Countryadd(string country, string id)
{
string data = "0";
try
{
string qry1 = "select Country from Country where Country='" + country + "'";//Checking weather txtcountry(Country Name) value is already exixst or not. If exist return 1 and not exists go to else condition
SqlDataReader dr = conn.query(qry1);
if (dr.Read())
{
return data = "1";
}
else
{
string qry = "insert into Country values('" + id + "','" + country + "')";
conn.nonquery(qry);
return data = "3";
}
}
catch (Exception ex)
{
string x = ex.Message();
}
return data;
}
this string value how can we set in a label
My button_click function is
protected void Button1_Click(object sender, EventArgs e)
{
string str = mas.Countryadd(txtcountry.Text, txtid.Text);
if (str == "1")
{
Response.Write("<script>alert('Country Already Exist!!!!')</script>");
}
else if (str == "3")
{
Response.Write("<script>alert('Country Added Succesfully')</script>");
}
else
{
Label1.Text = str;
}
}
It's not the prettiest of code. Returning a string as a kind of status code is generally bad practice, because you don't know the range of possible values which can be returned, and what they mean. At the very least consider integer or even enum (which is named).
That being said, I would handle the check and the insert in separate methods, and catch the exception in the click event handler - let a single method have a single responsibility:
private void AddCountry(string country, string id)
{
using (SqlConnection conn = new SqlConnection())
{
string sql = string.Format("INSERT INTO Country (Id, Country) VALUES ('{0}', '{1}')", id, country);
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.ExecuteNonQuery();
}
}
}
private bool Exists(string country, string id)
{
using (SqlConnection conn = new SqlConnection())
{
string sql = "SELECT Count(*) FROM Country WHERE Country='" + country + "'";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
int count = (int)cmd.ExecuteScalar();
return count >= 1;
}
}
}
private void Button1_Click(object sender, EventArgs e)
{
try
{
if (Exists(txtcountry.Text, txtid.Text))
{
Response.Write("<script>alert('Country Already Exist!!!!')</script>");
}
else
{
AddCountry(txtcountry.Text, txtid.Text);
Response.Write("<script>alert('Country Added Succesfully')</script>");
}
}
catch (Exception ex)
{
Label1.Text = ex.Message;
}
}
Catch(Exception e)
{
Label.Text= e.Message;
}
As in title. I tried to do everything, I searched on internet everywhere but it doesn't work. Here's the code:
public void SetIP(String IP, String Username)
{
try
{
String commandString = "UPDATE `Users` SET `IP` = '#ip' WHERE 'Username' = '#user';";
command = new MySqlCommand(commandString, connection);
command.Parameters.AddWithValue("#ip", IP);
command.Parameters.AddWithValue("#user", Username);
command.BeginExecuteNonQuery();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
I Correctly put both of values into Strings IP and Username. I get Username from TextBox and IP adress by doing this code:
public String GetIP()
{
String direction = "";
WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
using (WebResponse response = request.GetResponse())
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
direction = stream.ReadToEnd();
}
//Search for the ip in the html
int first = direction.IndexOf("Address: ") + 9;
int last = direction.LastIndexOf("</body>");
direction = direction.Substring(first, last - first);
return direction;
}
And I just call method SetIP like this: SetIP(GetIP(), UsernameBox.Text);
But when I come to the database to check if it changed it's still the same. All the time.
//Edit:
Got this error command: "There is already an open DataReader associated with this Connection which must be closed first."
I use this DataReaders:
public bool FindUsername(String Username)
{
String commandString = "select * from Users where Username = '" + Username + "';";
command = new MySqlCommand(commandString, connection);
MySqlDataReader connectionReader = command.ExecuteReader();
if (connectionReader.Read())
{
connectionReader.Close();
return true;
}
else
{
connectionReader.Close();
return false;
}
}
public bool FindEmail(String Email)
{
String commandString = "select * from Users where Email = '" + Email + "';";
command = new MySqlCommand(commandString, connection);
MySqlDataReader connectionReader = command.ExecuteReader();
if (connectionReader.Read())
{
connectionReader.Close();
return true;
}
else
{
connectionReader.Close();
return false;
}
}
public bool LoginSystem_FindUser(String Username, String Password)
{
String commandString = "select * from Users where Username = '"+Username+"' and Password = '"+Password+"' ;";
command = new MySqlCommand(commandString, connection);
MySqlDataReader connectionReader = command.ExecuteReader();
if (connectionReader.Read())
{
return true;
}
else
{
connectionReader.Close();
return false;
}
}
I'm using only "LoginSystem_FindUser" and after that SetIP, FindUser and FindEmail I use only for registration.
'Username' = '#user'
will always return to false because it compares literally.
It's because you parameters were wrapped with single quotes. Remove the single quotes and it will work.
String commandString = "UPDATE `Users` SET `IP` = #ip WHERE Username = #user;";
One more thing, column names are identifiers so they should also not be surrounded with single quotes.
I got it. I forgot
connectionReader.Close();
after if statement. Thanks BTW.