SQl from concatenation to parameters - c#

I have this sql connection with concatenated strings query and I would like to change it to parameters. I am starting coding on my own and I do not have many reference. Tried googling around but I have not found something clear enough to me.
public bool DBAuthenticate(string strUsername, string strPassword)
{
string sqlstring;
sqlstring = "SELECT * FROM credentials WHERE [Username]='" + strUsername + "' AND [Password]='" + strPassword + "'";
string getconnstring = ConfigurationManager.ConnectionStrings["WTAConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(getconnstring);
System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(sqlstring,conn);
System.Data.SqlClient.SqlDataReader reader;
conn.Open();
reader = comm.ExecuteReader();
if (reader.Read())
return true;
else
return false;
}
can someone please show me how to modify the code to change the query from concatenation to parameters? Thank you a lot.

In order to use parameters, you need to change your statement as follows:
SELECT * FROM credentials WHERE [Username]=#username AND [Password]=#password
It then contains two parameters (#username and #password) that you need to provide the values for in the command. You can do this with the AddWithValue method:
// ...
System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(sqlstring,conn);
comm.Parameters.AddWithValue("#username", strUsername);
comm.Parameters.AddWithValue("#password", password);
System.Data.SqlClient.SqlDataReader reader;
// ...
Please also note that you should always dispose the connection, commands and readers reliably, so adding some using blocks will help:
using(SqlConnection conn = new SqlConnection(getconnstring))
{
conn.Open();
using(SqlCommand comm = new System.Data.SqlClient.SqlCommand(sqlstring,conn))
{
// ...
using(SqlDataReader reader = comm.ExecuteReader())
{
// ...
}
}
}

Try this one:
sqlstring = "SELECT * FROM credentials WHERE [Username]=#UserName AND [Password]=#Password";
After the declaration of comm object, write this:
comm.Parameters.Add(new SqlParameter(#UserName,strUsername));
comm.Parameters.Add(new SqlParamter(#Password,strPassword);

Related

Parameterised QUERY in C# for simple login [duplicate]

This question already has answers here:
What are good ways to prevent SQL injection? [duplicate]
(4 answers)
Closed 4 years ago.
I have been doing simple website using ASP, but am not sure how to add parameterised query to avoid any SQL Injection attacks, can anybody help me to do it i always encounter errors and it has been more than a week that am doing and still i can't figured out. below i attached my simple code.
protected void btnLogin_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
string sql = "Select * From Users Where UserID='" + txtUser.Text + "' And Password='" + txtPwd.Text + "'";
con.Open();//opens the connection
//create the command object
cmd = new SqlCommand(sql, con);
//assigns the result to the reader
dr = cmd.ExecuteReader();
dr.Read();//read the record's data
//if there's a matching record found
if (dr.HasRows)
{
if (dr["UserType"].Equals("admin"))
{
Response.Redirect("dhome.aspx");
}
else if (dr["UserType"].Equals("staff"))
{
Response.Redirect("shome.aspx");
}
else if (dr["UserType"].Equals("member"))
{
Response.Redirect("mhome.aspx");
}
}
else
{
lblAlert.Text = "Invalid username or password!";
}
dr.Close(); //close the data reader
con.Close();//close the connection //declaration of data access components
}
You should add them using SqlCommand.Parameters.Add():
using (SqlConnection con = new SqlConnection(ConnectionString))
{
SqlCommand cmd = new SqlCommand("Select * From Users Where UserID=#username And Password=#password", con);
cmd.Parameters.Add("#username", SqlDbType.VarChar).Value = username;
cmd.Parameters.Add("#password", SqlDbType.VarChar).Value = password;
//rest of the code ...
}
You need to use SqlCommand.Parameters.Add. You should also implement dispose (via using blocks or calling Dispose) to release resources after use:
string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string sql = "Select * From Users Where UserID=#user And Password=#pwd";
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#user", SqlDbType.VarChar);
command.Parameters["#user"].Value = "value";
command.Parameters.Add("#pwd", SqlDbType.VarChar);
command.Parameters["#pwd"].Value = "value";
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
// read row
}
}
}

How to store the resulting string of a SQL query in C#

I have a table TümEnvanter$ which has 2 columns equipment code (Ekipman) and their description (Tanım).
User chooses the equipment from the combo box, and I want the description of the chosen equipment to appear in the label at the time they choose from combobox.
Here is what I tried:
SqlCommand cmdTanim = new SqlCommand("select Tanım from TümEnvanter$ where Ekipman = '" + comboBox_ekipman.Text + "'", connect);
connect.Open();
SqlDataReader reader = cmdTanim.ExecuteReader();
string tanim = reader.ToString();
labelTanim.Text = "Ekipman Tanımı: "+tanim+" ";
When I use this code, I get in the label:
Ekipman Tanımı: System.Data.SqlClient.SqlDataReader
How can I fix this? Thank you.
If you only expect a single value, then ExecuteScalar is much simpler than using a reader, i.e.
labelTanim.Text = Convert.ToString(cmdTanim.ExecuteScalar());
In general, perhaps consider tools like "Dapper" which would make this simple even in multi-row cases and solve the SQL injection problem trivially:
string s = connect.QuerySingle<string>(
"select Tanım from TümEnvanter$ where Ekipman = #val", // command
new { val = comboBox_ekipman.Text }); // parameters
You should try this code, it gathers some good practices, such as:
1) Uses using statement to release unamnaged resources (SQL connections, IDisposables in general).
2) Prevents from SQL injection using Parameters field of SqlCommand object.
Also, I used ExecuteScalar method, mentioned by #MarcGravell, which simplifies the code.
public void SqlConn()
{
string tanim = null;
using (SqlConnection connect = new SqlConnection("connectionString"))
{
using (SqlCommand cmdTanim = new SqlCommand())
{
cmdTanim.Connection = connect;
cmdTanim.CommandText = "select Tanım from TümEnvanter$ where Ekipman = #param";
cmdTanim.Parameters.Add("#param", SqlDbType.VarChar).Value = comboBox_ekipman.Text;
connect.Open();
tanim = (string)cmdTanim.ExecuteScalar();
}
}
labelTanim.Text = "Ekipman Tanımı: " + tanim + " ";
}
Something like this:
// wrap IDisposable into using
using (SqlConnection connect = new SqlConnection("Put_Connection_String_Here"))
{
connect.Open();
// Make SQL readable and parametrized
string sql =
#"select Tanım
from TümEnvanter$
where Ekipman = #prm_Ekipman";
// wrap IDisposable into using
using (SqlCommand cmdTanim = new SqlCommand(sql, connect))
{
//TODO: explicit typing Add(..., DbType...) is a better choice then AddWithValue
cmdTanim.Parameters.AddWithValue("#prm_Ekipman", comboBox_ekipman.Text);
// We want one record only; ExecuteScalar() instead of ExecuteReader()
// String interpolation shortens the code
labelTanim.Text = $"Ekipman Tanımı: {cmdTanim.ExecuteScalar()} ";
}
}
Use this code instead by using the reader() method of SqlDataReader to read and access the contents of the SqlDataReader.
SqlCommand cmdTanim = new SqlCommand("select Tanım from TümEnvanter$ where Ekipman = '" + comboBox_ekipman.Text + "'", connect);
connect.Open();
SqlDataReader reader = cmdTanim.ExecuteReader();
if(reader.HasRows){
reader.read();
string tanim = reader.ToString();
labelTanim.Text = "Ekipman Tanımı: "+tanim+" ";
}
Hope this code snippet works for you.
Use below code :
SqlCommand cmdTanim = new SqlCommand("select Tanım from TümEnvanter$ where Ekipman = '" + comboBox_ekipman.Text + "'", connect);
connect.Open();
SqlDataReader reader = cmdTanim.ExecuteReader();
string tanim = string.Empty;
while (reader.Read())
{
tanim= reader["Tanım"].ToString()
}
labelTanim.Text = "Ekipman Tanımı: "+tanim+" ";

no value given fr one or more required parameters

I'm trying to prevent SQL injections. Am I doing this right? (I'm using MS Access.) Should I still use sqlparameter?
OleDbParameter[] myparm = new OleDbParameter[2];
myparm[0] = new OleDbParameter("#UserID", UserName.Text);
myparm[1] = new OleDbParameter("#Password", encode);
string queryStr = "SELECT * FROM TMUser WHERE UserID=#UserID AND Password=#Password";
OleDbConnection conn = new OleDbConnection(_connStr);
OleDbCommand cmd = new OleDbCommand(queryStr, conn);
conn.Open();
OleDbDataReader dr = cmd.ExecuteReader();
Close!
string queryStr = "SELECT * FROM TMUser WHERE UserID=#UserID AND Password=#Password";
OleDbConnection conn = new OleDbConnection(_connStr);
OleDbCommand cmd = new OleDbCommand(queryStr, conn);
cmd.Parameters.AddWithValue("#UserID", UserName.Text);
cmd.Parameters.AddWithValue("#Password", encode);
The parameters are part of the command object and you use the Parameters.AddWithValue method to set the parameter values to what you have defined in the query string.
By the way, you should be using using statements to encapsulate some of your objects, here is what I typically do:
using (OleDbConnection conn = new OleDbConnection(_connStr))
using (OleDbCommand = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT ...";
cmd.Parameters.AddWithValue(...);
cmd.ExecuteReader();
//...
}
That way you don't have to worry about cleaning up resources if something goes wrong inside or closing the connection when you are done.

SQL Parameters in C# aren't working as expected

I think I'm making a fairly amateur mistake somewhere here, but I can't get SQL Parameters to reliably work in C#. Consider the following code:
protected string[] Query(string dataToFind, string tableName, string fieldToCheck, string fieldToReturn)
{
SqlConnection connection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
SqlDataReader dataReader = null;
SqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT " + fieldToReturn + " FROM " + tableName + " WHERE " + fieldToCheck " = '" + dataToFind "'";
try
{
connection.Open();
dataReader = command.ExecuteReader();
etc...
This executes as you would expect, returning the fieldToReturn from the table tableName. However, I understand that this is vulnerably to SQL injections, and that the correct way to avoid this is to use parameters. So I change my code to the following:
protected string[] Query(string dataToFind, string tableName, string fieldToCheck, string fieldToReturn)
{
SqlConnection connection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
SqlParameter[] parameters = new SqlParameter[4];
parameters[0] = new SqlParameter("#dataToFind", dataToFind);
parameters[1] = new SqlParameter("#name", tableName);
parameters[2] = new SqlParameter("#fieldToCheck", fieldToCheck);
parameters[3] = new SqlParameter("#fieldToReturn", fieldToReturn);
SqlDataReader dataReader = null;
SqlCommand command = connection.CreateCommand();
command.Parameters.AddRange(parameters);
command.CommandText = "SELECT #fieldToReturn FROM #tableName WHERE #fieldToCheck = #dataToReturn";
try
{
connection.Open();
dataReader = command.ExecuteReader();
etc...
If I have 3 matches in my database, the first code example returns 3 matches. The second code returns 0 results?!
Am I being stupid and missing something obvious?
Your parameters are:
#dataToFind
#name
#fieldToCheck
#fieldToReturn
Your Query's CommandText has:
#fieldToReturn
#tableName
#fieldToCheck
#dataToReturn
These do not match. They must match in order to be properly applied.

ado.net can't read from my database

This is a really noob-problem but im tearing my hair soon.
I'm trying to read from my local database but it gives me nothing.
Here is the code:
protected void readBtn2_Click(object sender, EventArgs e)
{
string ConnString = "server=localhost; Trusted_Connection=yes; database=expreimentalDB";
string SqlString = ("SELECT * FROM tblCity WHERE city = '#city'");
using (SqlConnection conn = new SqlConnection(ConnString))
{
using (SqlCommand cmd = new SqlCommand(SqlString, conn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("city", cityTB.Text);
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
GridView1.DataSource = reader;
GridView1.DataBind();
}
}
}
}
The connectionstring should work (because if i rename the database part in the string it crashes).
The sql is working (tried it in sql manager)
reader (the SqlDataReader) is empty
What is it I havnt tried out yet?
You need to remove the single quotes from around #city in your query so that it becomes
string SqlString = "SELECT * FROM tblCity WHERE city = #city";
and then
cmd.Parameters.AddWithValue("city", cityTB.Text);
needs to be changed to
cmd.Parameters.AddWithValue("#city", cityTB.Text);
I'm not quite sure, but shouldn't you have to prefix the name of the parameter with the #-sign when adding it to your command? Like this:
cmd.Parameters.AddWithValue("#city", cityTB.Text);

Categories

Resources