getting exception in creating a password change form - c#

i am creating password change form. when i execute the form and fill the textboxes it give an exception with the message There is already and open DataReader associated with this command which must be closed first.
he is the code which i am using:
private bool CompareStrings(string string1, string string2)
{
return String.Compare(string1, string2, true, System.Globalization.CultureInfo.InvariantCulture) == 0 ? true : false;
}
private void button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection con1 = new SqlConnection();
con1.ConnectionString = "data source=.;Initial catalog=inventory;Integrated Security=true";
con1.Open();
SqlCommand cmd = new SqlCommand("SELECT ISNULL(username, '') AS username, ISNULL(password,'') AS password FROM login WHERE username='" + textBox1.Text + "' and password='" + textBox2.Text + "'", con1);
SqlDataReader dr = cmd.ExecuteReader();
string userText = textBox1.Text;
string passText = textBox2.Text;
while (dr.Read())
{
if (this.CompareStrings(dr["username"].ToString(), userText) &&
this.CompareStrings(dr["password"].ToString(), passText))
{
SqlCommand cmd2 = new SqlCommand("UPDATE login SET password='" + textBox3.Text + "'where username='" + textBox1.Text + "'", con1);
cmd2.ExecuteNonQuery();
MessageBox.Show("Password Changed Successfully");
}
else
{
MessageBox.Show("Incorrect Old password");
}
}
dr.Close();
con1.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

You cannot execute a command while a SqlDataReader is open on the same connection. You can do either of the two following things to change your code:
Create a second connection and run the update query on that second connection.
Store the data from the reader, close the reader and later update all data. In your case, you could store all usernames to update and update them in one update query using Username in (<yourlisthere>)

When you open a DataReader the connection serves only the requests coming from the DataReader. The SqlCommand used to Update the login table cannot run.
Unless you add this to your connectionstring
MultipleActiveResultSets = True;
Here you can find the reference to MARS
And here the words from MSDN about the DataReader
While the SqlDataReader is being used, the associated SqlConnection is
busy serving the SqlDataReader, and no other operations can be
performed on the SqlConnection other than closing it. This is the case
until the Close method of the SqlDataReader is called. For example,
you cannot retrieve output parameters until after you call Close.
As a side note, but very important. Do not use string concatenation to build sql commands. Use always a parameterized query
string cmdText = "UPDATE login SET password=#pwd where username=#usr";
using(SqlCommand cmd2 = new SqlCommand(cmdText, con1))
{
cmd2.Parameters.AddWithValue("#pwd", textBox3.Text);
cmd2.Parameters.AddWithValue("#usr", textBox1.Text);
cmd2.ExecuteNonQuery();
}
A parameterized query will avoid Sql Injection problems and let you simplify your command text.
This is true also for the SELECT query at the beginning of your code. Do not trust the input coming from your user
Another problem that you should be aware of is the storing of clear text passwords in your database. This is considered a very bad practice from a security point of view. You should apply an hash function to you password and store the result. While checking for the correct password you repeat the hash function on the user input and check the result against the hashed password stored in database

Related

SQL Invalid Column name detection from Query

I've tried running the code and I have no idea what's wrong with the query. Because it keeps saying invalid column name, when I'm trying to retrieve the data from that column instead. The column name matches the one in the DB. It's well connected because it's connected to a login form where it detects the other given password and name. I'm using based on a search textbox.
private void btnSearch_Click(object sender, EventArgs e)
{
SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDetailConnectionString"].ToString());
try
{
cnn.Open();
SqlCommand command = new SqlCommand();
command.Connection = cnn;
string query = "SELECT *FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
command.CommandText = query;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
---[Converting String from db /Insert to textboxes]---
}
cnn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
}
}
You need to wrap the username text in quotes.
Your emitted sql script is gonna look like:
SELECT *FROM AffiliatedRegister WHERE Username=InputUserName
So SQL is trying to compare the column Username to the column InputUsername.
Once you wrap the user name in quotes, it would be:
SELECT *FROM AffiliatedRegister WHERE Username='InputUserName'
Your statement erred because you did not wrap your string in quotes so Sql interpeted it as on object and not a string. That being said there you should use parameters and not string concatenation.
Use parameters
Wrap your SqlConnection in a using block
You should specify the column order in the SELECT statement, do not use *.
Do not swallow an Exception unless you know how to recover from it
Update code
private void btnSearch_Click(object sender, EventArgs e)
{
// use ConnectionString property
// wrap in using block
using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDetailConnectionString"].ConnectionString))
{
try
{
SqlCommand command = new SqlCommand();
command.Connection = cnn;
// use parameters
// avoid *, specify columns instead
string query = "SELECT * FROM AffiliatedRegister WHERE Username= #userName";
command.CommandText = query;
// use parameters, I assumed the parameter type and length - it should be updated to the type and length specified in your table schema
command.Parameters.Add(new SqlParameter("#userName", SqlDbType.VarChar, 200) {Value = txtUser.Text });
// open as late as possible
cnn.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
// ---[Converting String from db / Insert to textboxes]-- -
}
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
// do not swallow the exception unless you know how to recover from it
throw;
}
}
}
Well first of all your query is very dangerous so please don't use it for production purpose.
Now what you need to do :-
In your query you need single quotes around the txtUser.Text.
Like this :-
"SELECT *FROM AffiliatedRegister WHERE Username='" + txtUser.Text
+ "'";
Resulting query : SELECT *FROM AffiliatedRegister WHERE Username = 'txtUser.Text';
You can also put double quotes like :-
...Username=\"" + txtUser.Text + "\"";
its complicated ;-) Earlier one is better for the reading purpose.
Why it did not run?
Because all values except integers must be passed inside single or double quotes in a query. Like :-
SELECT * FROM TABLE_NAME WHERE TABLE_NAME.COLUMN_NAME = "VALUE";
Now one very important thing please don't use these kinds of queries for production purpose. I guess you are in development phase so answering this question is not gonna ruin your life ...!!!
You can try to replace the your string: string query = "SELECT *FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
to: string query = "SELECT <yourcolumn> FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
I believe it is necessary to specify the column name.
Best regards

I want to check whether given record is in database or not

I want to check whether given record is in database or not. It is showing error "Invalid Column name"
private void SaveButton_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection("Data Source=PC308433;Initial Catalog=SampleDatabase;Persist Security Info=True;User ID=sa;Password=adm23");
conn.Open();
SqlCommand sc = new SqlCommand("select USERNAME from QuizTable where USERNAME=" + UserNameTextbox.Text + "", conn);
string result =Convert.ToString(sc.ExecuteNonQuery());//I dont know to store the result of query here.Pls help me
if (result == UserNameTextbox.Text)
MessageBox.Show("Welcome");
else
MessageBox.Show("Please register");
conn.Close();
}
You have to use ExecuteReader() for it, ExecuteNonQuery() is only for insert,update and delete statements, and use Contructor which takes CommandBehaviour enum with SingleRow, as it should have one row per username:
SqlDataReader rdr = sc.ExecuteReader(CommandBehavior.SingleRow);
if(rdr.Read() && (rdr["USERNAME"].ToString() == UserNameTextbox.Text))
MessageBox.Show("Welcome");
}
SideNote:
You should be using parameterized queries, currently you are open to sql injection.
Try this,
private void SaveButton_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection("Data Source=PC308433;Initial Catalog=SampleDatabase;Persist Security Info=True;User ID=sa;Password=adm23");
conn.Open();
SqlCommand sc = new SqlCommand("select USERNAME from QuizTable where USERNAME=#USERNAME", conn);
sc.Parameters.AddWithValue(#USERNAME,'"+UserNameTextbox.Text+"');
SqlDataReader dr = sc.ExecuteReader();//Use this line
if (dr.HasRows)
MessageBox.Show("Welcome");
else
MessageBox.Show("Please register");
conn.Close();
}
First of all, make sure you have USERNAME column in QuizTable.
Here is a complete snippet for you-
Note: Your column USERNAME may create conflict with sql server reserve words. You should change it i.e. USER_NAME or LOGINNAME.
try
{
string userName = UserNameTextbox.Text.Trim();
using (SqlConnection conn = new SqlConnection("Your Conn String"))
{
string sql="select USERNAME from QuizTable where USERNAME=#USERNAME";
using (SqlCommand command = new SqlCommand(sql,conn))
{
command.Parameters.AddWithValue("#USERNAME", userName );
connection.Open();
Object IsFound = command.ExecuteScalar();
connection.Close();
if (IsFound == null)
{
//if not found
}
else
{
//if found
}
}
}
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
You need to put quotes around the value of the username parameter.
Also, don't use string concatenation to build sql statements. You are way open to injection attacks.
you can try this , because you use executenonquery () , here i think use ExecuteReader()
First you need to check 'username' in table then
Plesae try this....
SqlCommand sc = new SqlCommand("select USERNAME from QuizTable where USERNAME='" + UserNameTextbox.Text + "'", conn);

C# ASP.NET Code doesn't insert data into my database, but doesn't throw any errors either

I am working on a project for a class. One of the requirements is that my program pulls information from a few textboxes on a web form and stores the values into a database. I have pulled information out of a database and figured putting stuff into one would be roughly the same process. When I tried however I get no errors, but when I open the database up there is nothing there either.
Code:
OleDbConnection con;
OleDbCommand com;
con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + #"C:\Users\D40010490\Desktop\GMDatabase.accdb");
com = con.CreateCommand();
try
{
con.Open();
lblError.Text = "Successfully Connected to Database";
String firstName = txtFirstName.Text;
String lastName = txtLastName.Text;
String email = txtEmail.Text;
String password = txtPassword.Text;
String cpassword = txtCPassword.Text;
String Description = txtDesc.Text;
com.CommandText = "INSERT INTO Users "
+ "(lastname, firstname, email, password) "
+ "VALUES (" + "'" +lastName+"'"
+ "'" + firstName +"'"+ "'"+email+"'"+ "'"+password+"');";
con.Close();
}
catch (Exception ex)
{
lblError.Text = ex.ToString();
}
please advise.
You never actually execute the command:
com.CommandText = "INSERT INTO Users "...
com.ExecuteNonQuery();
con.Close();
You should also get in the habit of using parameters instead of concatenating SQL (especially when dealing with users and passwords).
You need to call com.ExecuteNonQuery() in order to run the command.
Mark Cidade have reason , always you want insert in database you should execute the retrieve, check very good your code and bug if is necesary for resolve...

validating and changing a user's password

I have a simple C# windows form which acts as a login, but also has a form to change the password of a user.
When you click on Change Password the form loads with a text box of current password, new pass and confirm new pass, and one save button.
I have stored username in label so that current password can be checked if it is valid from database or not.
I am storing these in a table which I created in Microsoft SQL Server 2008.
The code is as follows so far.
SqlConnection connect = new SqlConnection(str);
connect.Open();
string username = label_username.Text;
string password = textBox_Current.Text;
string newPassword = textBox_New.Text;
string confirmPassword = textBox_Verify.Text;
string sqlquery = "UPDATE [Member] SET Password=#newpass where Username=#username";
SqlCommand cmd = new SqlCommand(sqlquery, connect);
cmd.Parameters.AddWithValue("#newpass", textBox_Verify.Text);
cmd.Parameters.AddWithValue("#username", label_username.Text);
cmd.Parameters.AddWithValue("#password", textBox_Current.Text);
cmd.Connection = connect;
cmd.ExecuteNonQuery();
sqlDataReader reader = null;
reader = cmd.ExecuteReader();
while (reader.Read())
{
if ((textBox_New.Text == reader["newPassword"].ToString()) & (textBox_Verify.Text == (reader["confirmPassword"].ToString()))) { }
}
MessageBox.Show("Password Changed Successfully!");
this.Close();
While executing above code, password change but I want to:
check validation like if the user had typed wrong password in current password.
newpassword and confirm password .
when user click on first save bottom blank password should not store in database, rather should give message 'please type the password'
How can this be done?
You really should not be storing these passwords in plain text. You should hash the password and store the hash. Then if you want to check if a password is correct hash the password the user typed and compare it to the hash stored for the user.
But, it sounds like you need help getting a value out of the database for the current user. Putting something like this in there, ought to do this for you. Please note that like I said above, this should really be retrieving a hash of the password, not the actual password in plain text.
string sqlquery = "SELECT Password FROM [Member] where Username=#username";
SqlCommand cmd = new SqlCommand(sqlquery, connect);
cmd.Parameters.AddWithValue("#username", label_username.Text);
cmd.Connection = connect;
string currentPassword = (string)cmd.ExecuteScalar();
if (currentPassword == textBox_Current.Text)
{
// PASSWORD IS CORRECT, CHANGE IT, NOW.
} else {
// WOW EASY BUDDY, NOT SO FAST
}
First you should use password hashing in your application, thus the password fields of the database should hold the hashed values.
Assuming this, to accomplish your goals,
consider your string username -> Hash it -> write a query to check whether that hashed value and the user's password's hash value stored in the database is the same
consider string password and string newPassword in your code -> Hash both -> check whether the hash values are the same
consider string password and string newPassword -> check whether each is null or the length is 0
Also you should perform these tasks in the following order:
1 -> 3 -> 2
Hope this helps...
protected void btn_PasswordChange(object sender, EventArgs e)
{
string constring = DataAccess.GetConnection();
SqlConnection con = new `SqlConnection`(constring);
{
if (con.State != ConnectionState.Open)
con.Open();
}
string str = "select * from tbl_MemberLogin where Password='" + txtoldpwd.Text + "'";
DataTable DT = new DataTable();
DT = objdut.GetDataTable(str);
if (DT.Rows.Count == 0)
{
lblmsg.Text = "Invalid current password";
lblmsg.ForeColor = System.Drawing.Color.Red;
}
else
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "update tbl_MemberLogin set Password='" + txtnewpwd.Text + "' where UserName='" + Session["UserName"].ToString() + "'";
cmd.ExecuteNonQuery();
lblmsg.Text = "Password changed successfully";
lblmsg.ForeColor = System.Drawing.Color.Green;
}
}

How do I validate user input with database C# for window form?

I am a newbie with c# and window form
I am doing a web service, and use a form which contain a datagridview, but am having quite a lot of problems.
How do I validate user input with a database, for example, when the user inserts a username, however the username already exists in the database, I should prompt the user to enter another username.
I tried before in previous thread that I validate that particular column with only user can enter 0 or 1....
how to validate particular column cell field when editing
Is it something similar?
Do I need a web method for this?
p.s basically what I want is to have a textbox field in a window form, in which the user will key in a username to add it to the database, however, when they click on the add button, if the user name already exists, there will be a prompt. If not it will add it to database using the insert web method.
The data is retrieve by web method... meaning that I have to use a web method to help me with this check right...but how?
my code for web method
[WebMethod]
public DataSet validateUserName()
{
SqlConnection conn =
new SqlConnection("Data Source=.\\SQLEXPRESS;
Initial Catalog=User;Integrated Security=True");
SqlCommand dbCommand = new SqlCommand();
dbCommand.CommandText =
#"SELECT COUNT(*)
FROM User
WHERE UserName=#UserName";
// this textusername is from the window form
dbCommand.Connection = conn;
SqlDataAdapter da;
da = new SqlDataAdapter();
da.SelectCommand = dbCommand;
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
this is my window form code
private void btnAdd_Click(object sender, EventArgs e)
{
WSBrandData validate = new WSBRandData();
if (validate.validateUserName(txtUserName.Text))
{
MessageBox.Show("UserName is allocated");
txtUserName.Text = "";
}
else
{
WSBrandData add = new WSBRandData();
String[] names = null;
names = Convert.ToString(DGVBrand.CurrentRow.Cells[1].Value).Split(';');
String tagg = txtUserName.Text + ";";
names[1] = tagg;
DGVBrand.DataSource = add.addUserName(Convert.ToInt32(DGVBrand.CurrentRow.Cells[0].Value), names[0], names[1], Convert.ToInt32(DGVBrand.CurrentRow.Cells[3].Value));
BindBrand();
}
}
Read about ASP.NET Web Services.
Start here :
[WebMethod]
public Boolean UserNameExists(String userName)
{
SqlConnection conn =
new SqlConnection("Data Source=.\\SQLEXPRESS;
Initial Catalog=User;Integrated Security=True");
SqlCommand dbCommand = new SqlCommand();
dbCommand.CommandText =
#"SELECT COUNT(*)
FROM User
WHERE UserName='" + userName + "'";
// this textusername is from the window form
dbCommand.Connection = conn;
conn.Open();
int matchesCount = int.Parse(dbCommand.ExecuteScalar().ToString());
conn.Close();
return matchesCount != 0;
}
In your forms application:
if (webReference.Type.UserNameExists(this.userNameTextBox.Text) )
{
// Do something
}
else
{
// Do something else
}
If you are using some webmethod to insert the data, then there must be some method to extract the data, based upon some value. Now pass the UserName to this method and search for it, if found then ask the user to provide a different UserName.
And if this not what you are looking for, then please explain your question a bit more.

Categories

Resources