Working on building a simple .NET web application using a SQL Server table created. I continuely get errors in regards to the SqlDataReader, and am stuck on where I'm going wrong.
Here is my error: Additional information: Incorrect syntax near the keyword 'Table'.
Here is my code:
EDIT:
bool authenticated = AuthenticateMe(txtUsername.Text, txtPassword.Text);
if (authenticated)
{
Response.Redirect("Home.aspx");
}
else
{
Response.Redirect("Default.aspx");
}
}
private bool AuthenticateMe(string username, string password)
{
// string ErrorMessage = "";
string connectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;Connect Timeout=30";
string commandText = "SELECT Username from [Table] where Username = #name AND Password = #pwd";
// try
// {
using (SqlConnection sqlConnection1 = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(commandText, sqlConnection1))
{
sqlConnection1.Open();
cmd.Parameters.AddWithValue("#name", username);
cmd.Parameters.AddWithValue("#pwd", password);
int result = (int)cmd.ExecuteNonQuery();
if (result > 0)
{
return true;
}
else
{
return false;
}
}
}
1st Version (prior to edit):
protected void bnLogin_Click(object sender, EventArgs e)
{
bool authenticated = AuthenticateMe(txtUsername.Text, txtPassword.Text);
if (authenticated)
{
Response.Redirect("Home.aspx");
}
else
{
Response.Redirect("Default.aspx");
}
}
private bool AuthenticateMe(string userName, string password)
{
string connectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;Connect Timeout=30";
SqlConnection sqlConnection1 = new SqlConnection(connectionString);
sqlConnection1.Open();
SqlCommand cmd = new SqlCommand("SELECT Username from Table where Username = userName");
cmd.Connection = sqlConnection1;
SqlDataReader reader = cmd.ExecuteReader();
Response.Write("Entered Sucessfully");
reader = cmd.ExecuteReader();
string localUserName = (string)reader["Username"];
sqlConnection1.Close();
if (userName.Equals(localUserName))
{
return true;
}
else
{
return false;
}
Table is a reserved keyword in SQL. Try putting square brackets around it:
SqlCommand cmd = new SqlCommand("SELECT Username from [Table] where Username = userName");
Table is a keyword. If your table is called Table, your sql must escape it. Try [Table].
Note also that you'll want to use a parameter for the username - i.e. where Username = #userName, where you also add a parameter with that name to the command with the appropriate value.
Your AuthenticateMe method seems a bit wrong and ineffective to authenticate the user
You use a reserved keyword (Table) without the proper delimiters
(Square brackets)
You don't pass the username and the password to the query that checks
if the user is present
You call two times the ExecuteReader (?)
You check the returned value from the query with the same value used
for the search (useless)
So you could rewrite the code in this way
private bool AuthenticateMe(string userName, string password)
{
string connectionString = #".....";
string commandText = "SELECT COUNT(*) from [Table] where Username = #name AND Pass = #pwd");
using(SqlConnection sqlConnection1 = new SqlConnection(connectionString))
using(SqlCommand cmd = new SqlCommand(commandText, sqlConnection1))
{
sqlConnection1.Open();
cmd.Parameters.AddWithValue("#name", username);
cmd.Parameters.AddWithValue("#pwd", password);
int result = Convert.ToInt32(cmd.ExecuteScalar());
return (result > 0);
}
}
Also, keep in mind that is considered a bad practice to store the passwords in the database in plain text. Some kind of hash function should be applied to the password memorized to forbid any security problem if someone get a copy of the database.
I think there are 2 issues with your SQL query.
"SELECT Username from Table where Username = userName"
Table is a reserved keyword. Use another name for the table or [Table].
The last part, Username = username, is also wrong. If your intention was to have a constant string there, you should consider putting the username in quotes \'username\'. Don't forget about the escape symbol. And if you want to pass a parameter to the SQLCommand, use #username in the query and pass the value this way
cmd.Parameters["#username"].Value = "Bob";
Related
I am having silly trouble with an UPDATE statement. I am trying to change password in a user table with UPDATE, and I keep getting "syntax error". Can't find the reason...
In my table, I have 6 different columns including username and password.
String salt = ""; // Initializing salt string variable to save the salt
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database_MT.accdb;Jet OLEDB:Database Password=********************");
con.Open(); //Opening the connection
OleDbCommand cmd1 = new OleDbCommand("UPDATE users SET password = #pass WHERE username = #user", con);
salt = CreateRandomSalt();
cmd1.Parameters.AddWithValue("#pass", hashPassword(newPasswordTextBox.Text, salt));
cmd1.Parameters.AddWithValue("#user", verifiedUser);
try
{
cmd1.ExecuteNonQuery();
this.DialogResult = DialogResult.OK;
}
catch (Exception ex)
{
string newException = ex.ToString();
ThreadExceptionForm newEx = new ThreadExceptionForm(newException);
newEx.ShowDialog();
}
The password columnname and/or the users table-name might be keywords, so you'll have to escape them.
In SQL Server you use brackets to do so:
UPDATE [users] SET [password] = #pass WHERE username = #user
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);
based on this tutorial: http://www.codeproject.com/Tips/423233/How-to-Connect-to-MySQL-Using-Csharp
I have a table
CREATE TABLE Employee {
ID int,
Name varchar(20),
Password varchar(20),
}
and now I have a new row
INSERT INTO employee(ID, Name, Password) VALUES (001, 'John', 'abc')
and here's how I try to receive the Password as a string from ID that is taken from TextBox
MySqlConnection connection = new MySqlConnection("Server=localhost; Database=sad - final project; Uid=root; Pwd=");
connection.Open();
try
{
MySqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT Password FROM employee WHERE ID = '" + Input_ID + "'";
MySqlDataAdapter adapter = new MySqlDataAdapter(command);
DataSet myDataSet = new DataSet();
adapter.Fill(myDataSet);
} catch blablabla
If Input_ID is 001, I expect to get a string from myDataSet that contains the password (which is "abc") so that I can compare it with password input from another textbox. How could I convert this myDataSet to String?
How about using ExecuteScalar instead:
var pwd = command.ExecuteScalar() as string;
and now you have the string. I'm not going to address the security concerns with your code in this answer, they are vast.
DataRow row = myDataSet.Tables[0].Row[0];
string password = row["Password"];
should get you the string.
You should use ExecuteScalar to get the password to string. Also you should use the using keyword to ensure proper disposal of your connection/command. Also, you need to use parameters in your select to prevent injection.
using (MySqlConnection connection = new MySqlConnection("Server=localhost; Database=sad - final project; Uid=root; Pwd=");
using (MySqlCommand command = new MySqlCommand("SELECT password FROM employee WHERE ID = #UserId", connection)
{
try
{
connection.Open();
command.Parameters.AddWithValue("#UserId", Input_ID);
var pwd = command.ExecuteScalar() as string;
//Do something with the stored password.
//Consider encryption and other security concerns when working with passwords.
}
catch (Exception ex)
{
//handle your exceptions
}
}
Bussiness Access Layer :
public static int login(string userlogin, string pwdlogin)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
int id = 0;
string selectstr = "SELECT UserName, Password FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
SqlCommand cmd = new SqlCommand();
cmd.CommandText = selectstr;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = con;
id = cmd.ExecuteNonQuery();
cmd = null;
con.Close();
return id;
}
Login.cs
protected void Button1_Click(object sender, EventArgs e)
{
int id = BusinessAccessLayer.login(userlogin.Text.Trim(), pwdlogin.Text.Trim());
if (id > 0)
{
message.Text = " valid";
}
else
{
message.Text = "in valid";
}
}
Okay, there are multiple things wrong here:
1) You should use using statements to make sure you close your connection and command even if exceptions are thrown
2) You should use parameterized SQL instead of putting the values directly into your SQL statement, to avoid SQL Injection Attacks
3) You appear to be storing passwords in plain text. Don't do that. Use a salted hash or something similar (ideally something slow to compute).
4) You're ignoring .NET naming conventions; methods should be in PascalCase
5) Your SQL never looks at any field which appears to be related to the user ID. It's not clear what you expect ExecuteNonQuery to return, but if you want the actual ID, you'll need to refer to it in the SQL. (Even if initially you just want to know whether or not the user's password is valid, I strongly suspect that at some point you'll want to user the real user ID, so you should make your code return it. If you really only want to know whether or not the password is valid, you should change the method's return type to bool.)
6) You're using ExecuteNonQuery when your command clearly is a query. Either use ExecuteReader or ExecuteScalar instead. (ExecuteNonQuery is meant for insert, delete and update statements, and it returns you the number of rows affected by the command.)
So something like:
public static int Login(string user, string password)
{
using (var conn = new SqlConnection(GetConnectionString()))
{
conn.Open();
string sql = "select Id, PasswordHash from logins where Username=#Username";
using (var command = new SqlCommand(sql))
{
command.Parameters.Add("#Username", SqlDbType.NVarChar).Value = user;
using (var reader = command.ExecuteRead())
{
if (reader.Read())
{
int id = reader.GetInt32(0);
string hash = reader.GetString(1);
// TODO: Hash provided password with the same salt and compare
// results
if (CheckPassword(password, hash))
{
return id;
}
}
return 0; // Or use an int? return type and return null
}
}
}
}
The ExecuteNonQuery is used for For UPDATE, INSERT, and DELETE statements.
For SELECT statements, use ExecuteReader
public static int login(string userlogin, string pwdlogin)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
int id = 0;
string selectstr = "SELECT UserName, Password FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
SqlCommand cmd = new SqlCommand();
cmd.CommandText = selectstr;
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;
}
You can't use .ExecuteNonQuery if you want a result. Use .ExecuteReader.
public static int login(string userlogin, string pwdlogin)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
int id = 0;
string selectstr = "SELECT UserId FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
SqlCommand cmd = new SqlCommand();
cmd.CommandText = selectstr;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = con;
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
id = reader.GetInt32("UserId");
reader.Close();
con.Close();
return id;
}
I am trying to develop a simple user management system for the admin of the web application. I am using ASP.NET Wizard Control for this task.
I just put a TextBox for writing the username and when the admin clicks on the Next button, the system should check if the username existed in the database or not. If it is existed, the system should display his information in a placeholder for the admin.
I am struggling with this task. I did the following in the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
//Session["Username"] = Username.Text;
string connString = "Data Source=localhost\\sqlexpress;Initial Catalog=testdb;Integrated Security=True";
string cmdText = "SELECT * FROM employee WHERE Username = #Username";
//For checking the user
if (Request.QueryString["Username"] != null)
{
String strUserName = Request.QueryString["Username"];
////Check userName Here
//String strReturnStatus = "false";
if (CheckUsername(Request.QueryString["Username"]) == true)
{
//strReturnStatus = "true";
try
{
SqlConnection conn = new SqlConnection(connString);
conn.Open();
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand(cmdText, conn);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine(myReader["Name"].ToString());
Console.WriteLine(myReader["Job"].ToString());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
//Response.Clear();
//Response.Write(strReturnStatus);
//Response.End();
}
}
private bool CheckUsername(string username)
{
string connString = "Data Source=localhost\\sqlexpress;Initial Catalog=testdb;Integrated Security=True";
string cmdText = "SELECT * FROM employee WHERE Username = '" + username + "'";
using(SqlConnection conn = new SqlConnection(connString))
{
conn.Open(); // Open DB connection.
using (SqlCommand cmd = new SqlCommand(cmdText, conn))
{
int count = (int)cmd.ExecuteScalar();
// True (> 0) when the username exists, false (= 0) when the username does not exist.
return (count > 0);
}
}
}
I tried to test this by writing any username in the TextBox, but I did not get any result when I clicked on Next button of the wizard that should redirect me to the placeholder or any control that should display the user information. What I want now is just showing the information of the user if his username existed in the database. How to do that?
First of all you need to understand the concept of page load and postbacks. The code written inside Page_Load will execute every time the page is loaded either by entering the URL in browser or by becuase of button click event. You should place the code that you want to execute only once in
if(!isPostback)
{
//code to be need to be executed for the first time
//only goes within this block
}
Then as Asken suggested have a look at SQL injection too
Now regarding the problem, in your Page_Load event you have:
string cmdText = "SELECT * FROM employee WHERE Username = #Username";
You need to set the value of #Username parameter and this is how you can do this:
myCommand.Parameters.Add("#Username", SqlDbType.VarChar, 30); //assumption: UserName column is of varchar type length of 30
nonqueryCommand.Parameters["#Username"].Value = strUserName;