How to give a proper error message [closed] - c#

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
According to my code "Your Password Has Been Changed successfully!, Congratulations!" message is popping up even though the update is not worked. how can I give an error message if the update is not taken place(It seems there is an error in my update statement too..). Actually I couldn't imagine how to use the if statement here..
protected void Button1_Click(object sender, EventArgs e)
{
MySqlConnection connection = new MySqlConnection("server=localhost; database=e-learningsystem; uid=root; password=123;port=3307;");
connection.Open();
try
{
MySqlCommand cmd1 = new MySqlCommand("UPDATE student Set Password= '" + TextBox3.Text + "' WHERE UserName='" + TextBox1.Text + "' AND Password='"+TextBox2.Text+"'", connection);
cmd1.ExecuteNonQuery();
Response.Write(#"<script language='javascript'>alert('Your Password Has Been Changed successfully!, Congratulations!')</script>");
connection.Close();
}
catch (Exception ex)
{
Response.Write(#"<script language='javascript'>alert(ex.Message)</script>");
}
}

cmd1.ExecuteNonQuery() returns the number of rows affected. So if your query updates any record then it will return more than 0 rows (in this case 1 row of that particular user)
So try this
if(cmd1.ExecuteNonQuery()>0)
{
// successfull
}
else
{
// failure
}
and Please do not pass values like this in your query. Try using SqlParameter to pass the parameters in query to avoid Sql Injection.

Sachin's Answer give you the solution for your message box popup issue.
But Why you implement your own authentication mechanism? is there any reason not to use asp.net membership providers?
Assume you have good reason to that. But if you are implementing custom authentication check this Sample Membership Provider Implementation
For example ChangePassword method :
public override bool ChangePassword(string username, string oldPwd, string newPwd)
{
// validate the user first, you are not doing any validation
// logged in user can change any other users password in your approach
if (!ValidateUser(username, oldPwd))
return false;
//new password validation and giving proper message if failed
// skip this code from given link
// use parameterized query as below
OdbcConnection conn = new OdbcConnection(connectionString);
OdbcCommand cmd = new OdbcCommand("UPDATE Users " +
" SET Password = ?, LastPasswordChangedDate = ? " +
" WHERE Username = ? AND ApplicationName = ?", conn);
cmd.Parameters.Add("#Password", OdbcType.VarChar, 255).Value = EncodePassword(newPwd);
cmd.Parameters.Add("#LastPasswordChangedDate", OdbcType.DateTime).Value = DateTime.Now;
cmd.Parameters.Add("#Username", OdbcType.VarChar, 255).Value = username;
cmd.Parameters.Add("#ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName;
int rowsAffected = 0;
try
{
conn.Open();
// this is how you can check whether row updated or not
rowsAffected = cmd.ExecuteNonQuery();
}
catch (OdbcException e)
{
// you need to have proper error handling as well
if (WriteExceptionsToEventLog)
{
WriteToEventLog(e, "ChangePassword");
throw new ProviderException(exceptionMessage);
}
else
{
throw e;
}
}
finally
{
conn.Close();
}
if (rowsAffected > 0)
{
return true;
}
return false;
}

Related

Forms app wont accept my SQL table column with usernames, but it will accept the password

I'm creating a forms application which needs a login function. I have set up the MySqL connection and have applied it to my form. It does answer to my to responses, giving me a respons with a pass or no pass, BUT this is only when I ask for it to only match the input with passwords in the database. I cannot get it to match both the usernames and the passwords, even though I seem to have configurated my table as it should be. I've got 3 columns with ID, username(brugernavn) and password.
I can get it to accept both credentials if I match the ID's with the right password, fx SELECT * FROM bruger WHERE password =#pass AND id=#usn
I'm still very new to programming so if I'm confused please let me know.
Is anyone able to help?
I've tried to change my parameters to something else, but that didnt do the trick. There didnt seem to be a problem with the actual table, as it could acces my information about the passwords and the ID's, so I tried changing some values and stuff from the username column, but it did no good. I have both the username and password using varchar(100) and the ID is using INT(11) as a primary.
MySqlConnection connection = new MySqlConnection("server=localhost;port=3306;username=root;password=;database=bruger");
public void openConnection()
{
if (connection.State == System.Data.ConnectionState.Closed)
{
connection.Open();
}
}
public void closeConnection()
{
if (connection.State == System.Data.ConnectionState.Open)
{
connection.Close();
}
}
public MySqlConnection GetConnection()
{
return connection;
}
private void Loginbutton_Click(object sender, EventArgs e)
{
DB db = new DB();
string username = textBoxBrugernavn.Text;
string password = textBoxPassword.Text;
DataTable table = new DataTable();
MySqlDataAdapter adapter = new MySqlDataAdapter();
MySqlCommand command = new MySqlCommand("SELECT * FROM bruger WHERE password =#pass AND brugernavn =#usn", db.GetConnection());
command.Parameters.Add("#usn", MySqlDbType.VarChar).Value = username;
command.Parameters.Add("#pass", MySqlDbType.VarChar).Value = password;
adapter.SelectCommand = command;
adapter.Fill(table);
if (table.Rows.Count > 0)
{
MessageBox.Show("YES");
}
else
{
MessageBox.Show("NO");
}
I was hoping this would let me run my forms apps and then let me login with already created users in my database. This however is not the case, as I am unable to match these two informations in the application.
Keep you data objects local. Then you can be sure they are closed and disposed. The using blocks take care of that even if there is an error. Since we only need one piece of data (the count) we can use ExecuteScalar which returns the first column of the first row in the result set. Of course, in a real application, you would never store passwords as plain text. They would be salted and hashed.
private void Loginbutton_Click(object sender, EventArgs e)
{
Int64 RecordCount = 0;
using (MySqlConnection cn = new MySqlConnection("server=localhost;port=3306;username=root;password=;database=bruger"))
{
using (MySqlCommand command = new MySqlCommand("SELECT Count(*) FROM bruger WHERE password =#pass AND brugernavn =#usn", cn))
{
command.Parameters.Add("#usn", MySqlDbType.VarChar).Value = textBoxBrugernavn.Text;
command.Parameters.Add("#pass", MySqlDbType.VarChar).Value = textBoxPassword.Text;
cn.Open();
RecordCount = (Int64)command.ExecuteScalar();
}
}
if (RecordCount > 0)
{
MessageBox.Show("YES");
//Add code to proceed to your next form
}
else
{
MessageBox.Show("NO");
}
}

How to Search in SQL Server Compact Database in windows form application using C#?

My Code For Searching Data In SQL Server Compact Database is not working please review my code. any help will be greatly appreciated.
#region btnSearch_Click
private void btnSearch_Click(object sender, EventArgs e)
{
SqlCeConnection con = new SqlCeConnection("Data Source="
+ System.IO.Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), "Database.sdf"));
sda = new SqlCeDataAdapter();
if (con.State == ConnectionState.Closed)
{
con.Open();
}
string sql = "select Name from tblCustomers ";
if (tbSearch.Text.Length > 0)
{
sql += "where Name like " + tbSearch.Text + " % ";
}
try
{
SqlCeCommand cmd = new SqlCeCommand(sql, con);
cmd.CommandType = CommandType.Text;
// if you don’t set the result set to
// scrollable HasRows does not work
SqlCeResultSet rs = cmd.ExecuteResultSet(
ResultSetOptions.Scrollable);
if (rs.HasRows)
{
int Name = rs.GetOrdinal("Name");
// Hold the output
StringBuilder output = new StringBuilder();
// Read the first record and get it’s data
rs.ReadFirst();
output.AppendLine(rs.GetString(Name)
+ " " + rs.GetString(Name));
while (rs.Read())
{
output.AppendLine(rs.GetString(Name)
+ " " + rs.GetString(Name));
}
// Set the output in the label
lblResults.Text = output.ToString();
}
else
{
lblResults.Text = "No Rows Found.";
}
}
catch (SqlCeException sqlexception)
{
MessageBox.Show(sqlexception.Message, "Error.",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error.",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
con.Close();
}
#endregion
it's throwing the bellow exception.
There was an error parsing the query. [ Token line number = 1,Token line offset = 53,Token in error = % ]
A useful way to solve such issues is to view the SQL string generated by your code right before sending it to SQL Server. If you can spot the problem immediately, that's great - fix it. If you can't try running the full query directly with the SQL Server Management Studio and see if you understand the problem. If you still can't post this query as a question on a Q&A site (just like here on SO) and it will be much easier to help you.
In this case, it looks to me like you're missing single quotes around the value ("like 'text'") - but I can't be sure cause it depends on the value of tbSearch.Text.

Assigning SQL reader leaves code

I am having an issue with my c# code. I am trying to check if a username exists already so I have a select statement but when I breakpoint it, it leaves the code right after I assign the reader. Here is my code:
SqlConnection conn = new SqlConnection(Properties.Settings.Default.CategoriesConnectionString);
SqlCommand chkUser = new SqlCommand("SELECT [Username] FROM [Accounts] WHERE [Username] = #username", conn);
chkUser.Parameters.AddWithValue("#username", txtUsername.Text);
conn.Open();
SqlDataReader sqlReader = chkUser.ExecuteReader(); //leaves code right here
if (sqlReader.HasRows)
{
MessageBox.Show("That username already exists. Please choose another.");
txtUsername.Focus();
return;
}
conn.Close();
I figure it is because there is nothing in the table yet but I don't know why it is not checking whether or not it has rows and is just leaving.
Any help is appreciated. Thanks
Some more information on the issue would be useful. Seems like you are getting an exception for some reason (as #Guffa said) and without any further details it becomes difficult guessing what the reason is. Try changing the code you posted to the following:
using(SqlConnection conn = new SqlConnection(Properties.Settings.Default.CategoriesConnectionString))
using(SqlCommand chkUser = new SqlCommand("SELECT [Username] FROM [Accounts] WHERE [Username] = #username", conn))
{
chkUser.Parameters.AddWithValue("#username", txtUsername.Text);
try
{
conn.Open();
using(SqlDataReader sqlReader = chkUser.ExecuteReader())
{
if (sqlReader.HasRows)
{
MessageBox.Show("That username already exists. Please choose another.");
txtUsername.Focus();
return;
}
}
}
catch(Exception e)
{
// manage exception
}
}
and see if something changes. In case it doesn't try debugging and see what kind of exception it throws.
Here is an example that i use in a login scenario where i've stored usernames in a mysql database table.
Even though i use MySQL there shouldnt be much of a difference.(not sure about this though).
public static string CheckUsername()
{
bool usernameCheck = false;
InitiateDatabase();//contains the root.Connection string
MySqlCommand readCommand = rootConnection.CreateCommand();
readCommand.CommandText = String.Format("SELECT username FROM `SCHEMA`.`USERTABLE`");
rootConnection.Open();
MySqlDataReader Reader = readCommand.ExecuteReader();
while (Reader.Read())
{
for (int i = 0; i < Reader.FieldCount; i++)
{
if (Reader.GetValue(i).ToString() == USERNAME_STRING)
{
usernameCheck = true;
}
}
}
rootConnection.Close();
if (usernameCheck)
{
return "Succes";
}
else
{
return "Wrong Username!";
}
}
This is of course without exception handling, which you might find useful during testing and if its meant to be used by others.

Show messages according to the MySQL database data? C#

I want to get the values from MySQL database and that would need to show the messages according to values. But it does not happen and that will always show int privilege is 0. If I did not assign that default value, errors will be showing on the code.
How can I solve this issue and show messages according to the int privilege values?
private void button_login_Click(object sender, RoutedEventArgs e)
{
string username = usernameInput.Text;
string password = passwordInput.Password;
int privilege = 0;
try
{
//This is command class which will handle the query and connection object.
string Query = "SELECT`tbl_user_login`.`u_id`,`tbl_user_login`.`u_username`,
`tbl_user_login`.`u_password`,`tbl_user_login`.`u_privilege`
FROM `bcasdb`.`tbl_user_login`WHERE `tbl_user_login`.`u_username` = '"
+ username + "' AND `tbl_user_login`.`u_password` ='" + password
+ "' AND `tbl_user_login`.`u_privilege` = #privi;";
MySqlConnection conn =
new MySqlConnection(BCASApp.DataModel.DB_CON.connection);
MySqlCommand cmd = new MySqlCommand(Query, conn);
cmd.Parameters.AddWithValue("#privi", privilege);
MySqlDataReader MyReader;
conn.Open();
MyReader = cmd.ExecuteReader();
// Here our query will be executed and data saved into the database.
if (MyReader.HasRows && this.Frame != null)
{
while (MyReader.Read())
{
if (privilege == 1)
{
DisplayMsgBox("click ok to open the admin page ", "OK");
}
if (privilege == 2)
{
DisplayMsgBox("click ok to open the staff page ", "OK");
}
else
{
DisplayMsgBox("privilege 0", "ok");
}
}
}
else
{
DisplayMsgBox("sucess else", "ok");
}
conn.Close();
}
catch (Exception )
{
DisplayMsgBox("sucess catch", "ok");
}
}
Looks like what you're trying to do is checking the value of u_privilege column from tbl_user_login table instead of making a where condition based on privilege. You need to remove this where condition
AND `tbl_user_login`.`u_privilege` = #privi
and also remove the parameter assignment
cmd.Parameters.AddWithValue("#privi", privilege);
You can get the value of tbl_user_login.u_privilege by using MySqlDataReader.GetInt32 syntax inside while (MyReader.Read()) block
MyReader.GetInt32(3)
Please note that 3 is used because MyReader.GetInt32 requires a zero based index parameter and tbl_user_login.u_privilege is the fourth column from your query. The value should be assigned to privilege variable as below
privilege = MyReader.GetInt32(3)
On a side note, you should parameterize your query to avoid SQL injection. Here's the complete code after implementing the above changes
int privilege = 0;
try
{
//This is command class which will handle the query and connection object.
string Query = "SELECT`tbl_user_login`.`u_id`,`tbl_user_login`.`u_username`,
`tbl_user_login`.`u_password`,`tbl_user_login`.`u_privilege`
FROM `bcasdb`.`tbl_user_login`WHERE `tbl_user_login`.`u_username` =
#username AND `tbl_user_login`.`u_password` = #password;";
MySqlConnection conn =
new MySqlConnection(BCASApp.DataModel.DB_CON.connection);
MySqlCommand cmd = new MySqlCommand(Query, conn);
cmd.Parameters.AddWithValue("#username", username);
cmd.Parameters.AddWithValue("#password", password);
MySqlDataReader MyReader;
conn.Open();
MyReader = cmd.ExecuteReader();
// Here our query will be executed and data saved into the database.
if (MyReader.HasRows && this.Frame != null)
{
while (MyReader.Read())
{
privilege = MyReader.GetInt32(3)
if (privilege == 1)
{
DisplayMsgBox("click ok to open the admin page ", "OK");
}
if (privilege == 2)
{
DisplayMsgBox("click ok to open the staff page ", "OK");
}
else
{
DisplayMsgBox("privilege 0", "ok");
}
}
}
else
{
DisplayMsgBox("sucess else", "ok");
}
conn.Close();
}
catch (Exception )
{
DisplayMsgBox("sucess catch", "ok");
}
If im not wrong, the privilege is being returned as a string type. Try take it in as a string then cast it to an integer?

Using Prepared Statement in C# with Mysql

I tried prepared statement in my program, but not working.
The part commented is the Prepared Statement part. When I change it into normal statement, everything is right.
Can someone tell me what am I missing?
Many thanks.
private void btnLogin_Click(object sender, EventArgs e)
{
MySqlCommand cmd = MySqlConn.cmd;
//cmd = new MySqlCommand("SELECT * FROM admin WHERE admin_username='#val1' AND admin_password=PASSWORD('#val2')", MySqlConn.conn);
//cmd.Prepare();
//cmd.Parameters.AddWithValue("#val1", tboxUserName.Text);
//cmd.Parameters.AddWithValue("#val2", tboxPassword.Text);
cmd = new MySqlCommand("SELECT * FROM admin WHERE admin_username='"+tboxUserName.Text+"' AND admin_password=PASSWORD('"+tboxPassword.Text+"')", MySqlConn.conn);
MySqlDataReader res = cmd.ExecuteReader();
if (!res.HasRows) { MessageBox.Show("Error! "); res.Close(); return; }
else
{
//do something
}
res.Close();
}
Try removing ' from your query and use Prepare after adding parameters:
cmd = new MySqlCommand("SELECT * FROM admin WHERE admin_username=#val1 AND admin_password=PASSWORD(#val2)", MySqlConn.conn);
cmd.Parameters.AddWithValue("#val1", tboxUserName.Text);
cmd.Parameters.AddWithValue("#val2", tboxPassword.Text);
cmd.Prepare();
Your solution is almost correct as-is. However, being this is a log-in process and thus a security-oriented task, there are a few suggestions I would like to make as well.
First, consider making your button event handler appear as follows:
private void btnLogin_Click(object sender, EventArgs e)
{
if (Login(tboxUserName.Text, tboxPassword.Text))
{
// Log in was successful, do something...
}
else
{
// Log in was NOT successful, inform the user...
}
}
This will make maintenance and readability of the application easier. Then declare a function named Login() to perform the heavy lifting:
private bool Login(string username, string password)
{
try
{
MySqlCommand cmd = MySqlConn.cmd;
cmd = new MySqlCommand(
"SELECT count(*) FROM admin " +
"WHERE admin_username=#username " +
"AND admin_password=PASSWORD(#passwd)",
MySqlConn.conn);
cmd.Prepare();
cmd.Parameters.AddWithValue("#username", username);
cmd.Parameters.AddWithValue("#passwd", password);
int result = (int)cmd.ExecuteReader();
// Returns true when username and password match:
return (result > 0);
}
catch (Exception e)
{
// Optional: log exception details
// Deny log in if an error has occurred:
return false;
}
}
You will notice a few things here. First, the quotes were removed from your original query string that were preventing the named parameters from working correctly. Additionally, the query returns a count() function result instead of attempting to create a result set containing the administrator username and password. Lastly, the method is encapsulated in a try-catch block , such that in the event an error occurs, the method returns false and the log in is denied. I also broke the query into a concatenated string for easier readability.

Categories