Method returns empty string in ASP.Net - c#

I'm having trouble with this method. It returns empty string, what is wrong with this ?
I have this method:
public static string GetData(string Table1, string Column1, string WhereColumn, string WhereValue)
{
Table1 = Methods.cleaninjection(Table1); // Some injection method that cleans the string
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["connection"].ConnectionString);
SqlCommand command = new SqlCommand("SELECT " + "#Column1" + " FROM " + Table1 + " WHERE " + "#WhereColumn" + " = " + "#WhereValue", connection);
command.Parameters.AddWithValue("Column1", Column1);
command.Parameters.AddWithValue("WhereColumn", WhereColumn);
command.Parameters.AddWithValue("WhereValue", WhereValue);
try
{
if ((connection.State == ConnectionState.Closed) || (connection.State == ConnectionState.Broken))
{
connection.Open();
}
string veri = Convert.ToString(command.ExecuteScalar());
return veri;
}
finally
{
connection.Close();
}
}
When I run this, the command string looks like this:
SELECT #Column1 FROM Table1 WHERE #WhereColumn = #WhereValue
It looks like correct but I couldn't find what is wrong.
Any ideas?

As commented, you cannot parameterize your column names and table names. Instead, do string concatenation:
"SELECT " + Column1 + " FROM " + Table1 + " WHERE " + WhereColumn + " = #WhereValue";
Here is how your code should be:
public static string GetData(string Table1, string Column1, string WhereColumn, string WhereValue)
{
Table1 = Methods.cleaninjection(Table1); // My injection method that cleans the string
string sql = "SELECT " + Column1 + " FROM " + Table1 + " WHERE " + #WhereColumn + " = #WhereValue";
using (SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["connection"].ConnectionString))
{
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#WhereValue", SqlDbType.VarChar, 50).Value = WhereValue;
connection.Open();
string veri = Convert.ToString(command.ExecuteScalar());
return veri;
}
}
}
Notes:
Please do not use AddWithValue. Use Parameters.Add() instead. According to this article:
There is a problem with the AddWithValue() function: it has to infer
the database type for your query parameter. Here’s the thing:
sometimes it gets it wrong.
Wrap your object in Using to ensure proper cleanup of resources.
For additional security purposes, you can wrap your column name and table name in square brackets [].

Related

objDataReader is Null - ASP.NET C#

I am quite new to ASP.NET and C#, so I still do not have much of an idea as to how things work. I basically get an error when I run my program and create a maintenance task. My code is shown right below:
private DataTable getMaintenance()
{
DataTable maintenance_dt = new DataTable();
maintenance_dt.Columns.Add("maintenance_ID");
maintenance_dt.Columns.Add("DAILY_MAINTENANCE");
maintenance_dt.Columns.Add("ADMIN_COMMENT");
string SQLstr = "SELECT MAINTENANCE_ID,DAILY_MAINTENANCE,ADMIN_COMMENT FROM " + maintenance_table + " where " + key + " like " + value + " order by MAINTENANCE_ID ";
using (DataTableReader objDataReader = OS.OSFunctions.executeSQLQuery(SQLstr))
{
while (objDataReader.Read())
{
DataRow mItem = maintenance_dt.NewRow();
mItem[0] = objDataReader["MAINTENANCE_ID"].ToString();
mItem[1] = objDataReader["DAILY_MAINTENANCE"].ToString();
if (objDataReader["ADMIN_COMMENT"] != DBNull.Value)
{
mItem[2] = objDataReader["ADMIN_COMMENT"].ToString();
}
else
{
mItem[2] = "";
}
maintenance_dt.Rows.Add(mItem);
}
}
return maintenance_dt;
}
The error I get from running this states
Object reference not set to an instance of an object. objDataReader was null
This occurs when I attempt to create a maintenance task. The code for that is also below right here:
protected void createMaintenance_Click(object sender, System.EventArgs e)
{
string SQLstr;
if (txtMaintenanceName.Text.Length > 0)
{
if (maintenance_table == "ACTIVE_DAILYMAINTENANCE")
{
SQLstr = "SELECT TOP(1) MAINTENANCE_ID FROM ACTIVE_DAILYMAINTENANCE WHERE SCHEDULE_DATE = " + value + " ORDER BY MAINTENANCE_ID desc";
using (DataTableReader objDataReader = OS.OSFunctions.executeSQLQuery(SQLstr))
{
if (objDataReader.Read())
{
int id = Convert.ToInt32(objDataReader["Maintenance_ID"]) + 1;
SQLstr = "insert into " + maintenance_table + " (maintenance_id, DAILY_MAINTENANCE, " + key + ", ADMIN_COMMENT) values ('" + id + "',"
+ " '" + txtMaintenanceName.Text + "'," + value + ",'" + txtAdminMaintenanceComment.Text + "')";
OS.OSFunctions.executeSQLNonQuery(SQLstr);
}
}
}
else
{
SQLstr = "insert into " + maintenance_table + "(DAILY_MAINTENANCE, " + key + ", ADMIN_COMMENT) values ('" + txtMaintenanceName.Text + "'," + value + ",'" + txtAdminMaintenanceComment.Text + "')";
OS.OSFunctions.executeSQLNonQuery(SQLstr);
}
}
Again, it is the getMaintenance() method giving me the error. This also isn't all my code, I do call the getMaintenance() function sometime later in the code for CreateMaintenance. Any help would be greatly appreciated.
EDIT: CODE TRYING OUT DATA SET
private DataSet getMaintenance()
{
DataSet maintenance_ds = new DataSet();
string SQLstr= "SELECT MAINTENANCE_ID,DAILY_MAINTENANCE,ADMIN_COMMENT FROM " + maintenance_table + " where " + key + " like " + value + " order by MAINTENANCE_ID ";
using(SqlConnection connection=new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(SQLstr, connection);
adapter.Fill(maintenance_ds);
return maintenance_ds;
}
}
So, you execute
DataTableReader objDataReader = OS.OSFunctions.executeSQLQuery(SQLstr)
in your using. SQLstr is
"SELECT MAINTENANCE_ID,DAILY_MAINTENANCE,ADMIN_COMMENT FROM " + maintenance_table + " where " + key + " like " + value + " order by MAINTENANCE_ID ";
You will need to use a debugger and jump to this line just before the error is thrown. First of all, you will need to find out what maintenance_table, key and value is. Try finding out what the generated query is and run it in your RDBMS, I think it will most likely return a null for some reason.
It is possible that you are just missing a wildcard character of % being wrapped around value if you have the intention to have a "contains" rather than an "equals" check.
Anyway, in order to detect what the error is you will need to find out what is being generated and why your query results in a null. Once you know what the problem is, you will also know what you need to fix, which largely simplifies the problem.
Since you do not use a parameterized query, I have to mention that if any of the dynamic values you concatenate to the query may come from untrusted sources, such as user input, then your query is vulnerable to SQL injection and you will need to protect your project against this potential exploit.
You do realize that you can send the sql to a datatable, and the columns and the data table is created for you.
so, use this code to get/return a data table.
It not clear if you "else" is to update a existing row, or insert a new one, but the code can look somthing like this:
protected void createMaintenance_Click(object sender, System.EventArgs e)
{
DateTime value = DateTime.Today;
string maintenance_table = "";
string SQLstr = "";
string key = "";
if (txtMaintenanceName.Text.Length > 0)
{
if (maintenance_table == "ACTIVE_DAILYMAINTENANCE")
{
// add new row
int id = NextMaintID(value);
string strSQL = #"SELECT * FROM " + maintenance_table + " WHERE Maintenance_ID = 0";
DataTable rstSched = MyRst(strSQL);
DataRow MyNewRow = rstSched.NewRow();
MyNewRow["maintenance_id"] = id;
MyNewRow["DAILY_MAINTENANCE"] = txtMaintenanceName.Text;
MyNewRow["ADMIN_COMMENT"] = txtAdminMaintenanceComment.Text;
rstSched.Rows.Add(MyNewRow);
MyUpdate(rstSched, strSQL);
}
}
else
{
// update (or add to daily?????
string strSQL = #"SELECT * FROM " + maintenance_table + " WHERE Maintenance_ID = " + key;
DataTable rstSched = MyRst(strSQL);
DataRow MyRow = rstSched.Rows[0];
MyRow["DAILY_MAINTENANCE"] = txtMaintenanceName.Text;
MyRow["ADMIN_COMMENT"] = txtAdminMaintenanceComment.Text;
MyUpdate(rstSched, strSQL);
}
}
So, I only need a few helper routines - (make them global in a static class - you can then use it everywhere - saves boatloads of code.
so these were used:
public DataTable MyRst(string strSQL)
{
// return data table based on sql
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
public DataTable MyRstP(SqlCommand cmdSQL)
{
// return data table based on sql command (for parmaters)
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
void MyUpdate(DataTable rstData, string strSQL)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
da.Update(rstData);
}
}
}
and of course this:
int NextMaintID (DateTime value)
{
int result = 0;
string SQLstr = #"SELECT TOP(1) MAINTENANCE_ID FROM ACTIVE_DAILYMAINTENANCE
WHERE SCHEDULE_DATE = #scDate ORDER BY MAINTENANCE_ID desc";
SqlCommand cmdSQL = new SqlCommand(SQLstr);
cmdSQL.Parameters.Add("#scDate", SqlDbType.Date).Value = value;
DataTable rstNextID = MyRstP(cmdSQL);
result = ((int)rstNextID.Rows[0]["Maintenance_ID"]) + 1;
return result;
}
So, how do you eat a elephant?
Answer: One bite at a time!!!
So, break out just a "few" helper routines that allows data operations against a data table object. That update command will work with edits, adds to rows, and even delete row method of a single row. All such updates can be thus be done with ONE simple update command.

my update c# code is not working,can i update two relational table at once?

i was trying to update two tables at once, but i got some syntax error on update code could u give me some idea? the insert code works perfect and i tried to copy the insert code and edit on update button clicked
here is my code
private void button2_Click(object sender, EventArgs e)
{
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
conn.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;" +
#"Data source= C:\Users\user\Documents\Visual Studio 2010\Projects\WindowsFormsApplication1\WindowsFormsApplication1\crt_db.accdb";
try
{
conn.Open();
String Name = txtName.Text.ToString();
String AR = txtAr.Text.ToString();
String Wereda = txtWereda.Text.ToString();
String Kebele = txtKebele.Text.ToString();
String House_No = txtHouse.Text.ToString();
String P_O_BOX = txtPobox.Text.ToString();
String Tel = txtTel.Text.ToString();
String Fax = txtFax.Text.ToString();
String Email = txtEmail.Text.ToString();
String Item = txtItem.Text.ToString();
String Dep = txtDep.Text.ToString();
String k = "not renwed";
String Remark = txtRemark.Text.ToString();
String Type = txtType.Text.ToString();
String Brand = txtBrand.Text.ToString();
String License_No = txtlicense.Text.ToString();
String Date_issued = txtDate.Text.ToString();
String my_querry = "update crtPro set Name='" + Name + "',AR='" + AR + "',Wereda='" + Wereda + "',Kebele='" + Kebele + "',House_No='" + House_No + "',P_O_BOX='" + P_O_BOX + "',Tel='" + Tel + "',Fax='" + Fax + "',Email='" + Email + "',Item='" + Item + "',Dep='" + Dep + "','" + k + "',Remark='" + Remark + "' where Name='" + Name + "' ";
OleDbCommand cmd = new OleDbCommand(my_querry, conn);
cmd.ExecuteNonQuery();
String my_querry1 = "SELECT max(PID) FROM crtPro";
OleDbCommand cmd1 = new OleDbCommand(my_querry1, conn);
string var = cmd1.ExecuteScalar().ToString();
String ki = txtStatus.Text.ToString();
String my_querry2 = "update crtItemLicense set PID=" + var + ",Type='" + Type + "',Brand='" + Brand + "',License_No='" + License_No + "',Date_issued='" + Date_issued + "' where PID=" + var + "";
OleDbCommand cmd2 = new OleDbCommand(my_querry2, conn);
cmd2.ExecuteNonQuery();
MessageBox.Show("Message added succesfully");
}
catch (Exception ex)
{
MessageBox.Show("Failed due to" + ex.Message);
}
finally
{
conn.Close();
}
The most likely problem based on the little information given (what database are you using for example - SQL Server 2012?), is that the datatype you are providing in the concatenated dynamic sql does not match the datatype of the column in the database. You've surrounded each value with quotes - which means it will be interpreted as a varchar. If you've got a date value in the wrong format (ie if Date_Issued is a date column) or if it is a number column, then it will error.
The solution is to replace your dynamic SQL with a parameterized query eg:
String my_querry = "update crtPro set Name=#name, AR=#ar, Wereda=#Wereda, etc ...";
OleDbCommand cmd = new OleDbCommand(my_querry, conn);
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#name", Name);
cmd.Parameters.AddWithValue("#myParam", Convert.ToDateTime(txtDate.Text.Trim()));
...
cmd.ExecuteNonQuery();
You can read about it further here
PS Make sure your parameters are in the same order as they are used in the SQL, because oledbcommand doesn't actually care what you call them. see here

Data type mismatch exception in Access query

I have the following code:
public void GetParameterSelectionSet(int wire, int bond, string processProgramPath)
{
string connectionString = "Provider=Microsoft.JET.OLEDB.4.0;" + "data source=" + processProgramPath + ";";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
connection.Open();
using (OleDbCommand command = new OleDbCommand("SELECT * " +
"FROM BONDS INNER JOIN WIRES on " +
"BONDS.WireID = WIRES.WireID " +
"WHERE (WIRES.OperationOrder = '#WireOrder') AND" +
"(BONDS.OperationOrder = '#BondOrder')", connection))
{
command.Parameters.Add(new OleDbParameter("#WireOrder", OleDbType.Numeric));
command.Parameters.Add(new OleDbParameter("#BondOrder", OleDbType.Numeric));
command.Parameters["#WireOrder"].Value = wire;
command.Parameters["#BondOrder"].Value = bond;
var mytemp = command.ExecuteScalar();
}
}
}
When I execute this query i get a "Data Type mismatch in criteria expression".
Both WIRES.OperationOrder and BONDS.OperationOrder are of type Numeric. So I am lost as to why this is failing.
Thanks in advance!
You have put quotes around your numeric parameters in the SELECT statement, which is incorrect.

how can i set the parameters for the sql query optional?

I build a Web Service in ASP.Net which sends me a list of rooms.
The parameters are id's which are separated by a comma.
I saved them to a string and build a sql select query.
When I send all 4 parameters I everything works fine and I get a result. But when I send less then 4 I get an error.
System.Data.SqlClient.SqlException: Incorrect syntax near ')'.
How can I set my the parameters optional in the sql query to select just the values I entered?
Here is my code so far:
internal static List<RAUM> Raum(string RAUMKLASSE_ID, string STADT_ID, string GEBAEUDE_ID, string REGION_ID)
{
List<RAUM> strasseObject = new List<RAUM>();
string raumklasseid = RAUMKLASSE_ID;
string gebaudeid = GEBAEUDE_ID;
string stadtid = STADT_ID;
string regionid = REGION_ID;
using (SqlConnection con = new SqlConnection(#"Data Source=Localhost\SQLEXPRESS;Initial Catalog=BOOK-IT-V2;Integrated Security=true;"))
using (SqlCommand cmd = new SqlCommand(#"SELECT r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID FROM RAUM r WHERE RAUMKLASSE_ID IN (" + raumklasseid + ") AND STADT_ID IN (" + stadtid + ") AND GEBAEUDE_ID IN (" + gebaudeid + ") AND REGION_ID IN (" + regionid + ")", con))
{
con.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
if (rdr["BEZEICHNUNG"] != DBNull.Value && rdr["ID"] != DBNull.Value)
{
strasseObject.Add(new RAUM()
{
RaumName = rdr["BEZEICHNUNG"].ToString(),
RaumID = rdr["ID"].ToString()
});
}
}
}
}
return strasseObject;
}
Thanks in advance for your help.
Imagine the parameter REGION_ID is an empty string. That part of your query will be something like:
...AND REGION_ID IN ()...
Because in AND REGION_ID IN (" + regionid + ")" the regionid variable will be replaced with an empty string. This is not valid SQL syntax so you'll get that exception.
Declare a function like this:
private static void AppendConstrain(StringBuilder query, string name, string value)
{
if (String.IsNullOrWhiteSpace(value))
return;
if (query.Length > 0)
query.Append(" AND ");
query.AppendFormat("{0} IN ({1})", name, value);
}
Then change your code to build the query in this way:
StringBuilder constrains = new StringBuilder();
AppendConstrain(contrains, "RAUMKLASSE_ID", RAUMKLASSE_ID);
AppendConstrain(contrains, "GEBAEUDE_ID", GEBAEUDE_ID);
AppendConstrain(contrains, "STADT_ID", STADT_ID);
AppendConstrain(contrains, "REGION_ID", REGION_ID);
StringBuilder query =
new StringBuilder("SELECT r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID FROM RAUM r");
if (constrains.Length > 0)
{
query.Append(" WHERE ");
query.Append(constrains);
}
using (SqlCommand cmd = new SqlCommand(query.ToString(), con))
{
// Your code...
}
WARNING: DO NOT USE this code in production or when the input comes from the user because it's vulnerable to SQL injection. For better approaches (do not stop to the accepted answer) see Parameterize an SQL IN clause
It always be a better approach to write the stored procedures and pass the parameters. But in your approach you should split your query because of not sure the values. So, your code be something like that..
Test it yourself, i didnt check it
string raumklasseid = RAUMKLASSE_ID;
string gebaudeid = GEBAEUDE_ID;
string stadtid = STADT_ID;
string regionid = REGION_ID;
string whereClause = string.Empty;
if (!string.IsNullorEmpty(raumklasseid))
{
whereClause = "RAUMKLASSE_ID IN (" + raumklasseid + ")";
}
if (!string.IsNullorEmpty(stadtid ))
{
if(string.IsNullorEmpty(whereClause)
whereClause = "STADT_ID IN (" + stadtid + ")";
else
whereClause += "AND RSTADT_ID IN (" + stadtid + ")";
}
if (!string.IsNullorEmpty(stadtid ))
{
if(string.IsNullorEmpty(whereClause)
whereClause = "STADT_ID IN (" + stadtid + ")";
else
whereClause += "AND RSTADT_ID IN (" + stadtid + ")";
}
if (!string.IsNullorEmpty(regionid))
{
if(string.IsNullorEmpty(whereClause)
whereClause = "REGION_ID IN (" + regionid + ")";
else
whereClause += "AND REGION_ID IN (" + regionid + ")";
}
if(!string.IsNullorEmpty(whereClause)
whereClause = "WHERE " + whereClause ;
// now your cmd should be like that
using (SqlCommand cmd = new SqlCommand(#"SELECT r.BEZEICHNUNG AS BEZEICHNUNG, r.ID AS ID FROM RAUM r " + whereClause , con))

How can i select from table where tablename is specified as SqlParameter?

I am trying to perform dynamic sql select where I am selecting from a table using a parameter.
SELECT null FROM #TableName
However I am getting error must declare table variable #TableName. I suspect this is because I am selecting from a table using a variable. I have not needed to do this before.
List<SqlParameter> sqlParams = new List<SqlParameter>()
{
new SqlParameter("TableName", "testtable"),
new SqlParameter("FieldName", "testfield"),
new SqlParameter("Find", "testfind"),
};
string sqlSelect = "SELECT null FROM #TableName
WHERE #FieldName LIKE '%' + #Find + '%' ";
DataTable dtSelect = SqlHelper.ExecuteDataset(sqlConn, CommandType.Text,
sqlSelect, 30, sqlParams.ToArray()).Tables[0];
//30 = timeout
How can I perform the above using dynamic sql? (no stored procedures please)
You cannot use parameters for things like table and column names. For those you could have a whitelist of possible values and then use string concatenation when building the SQL query.
You can't use parameters like that, so you have to build the query as a string. You could do that in SQL, but you can also just create the string in the C# code.
Make sure that the table name and field name are safe and trusted values, and doesn't come directly from an unsafe source like a web request.
string tableName = "testtable";
string fieldName = "testfield";
List<SqlParameter> sqlParams = new List<SqlParameter>() {
new SqlParameter("Find", "testfind"),
};
string sqlSelect =
"SELECT null " +
"FROM " + tableName + " " +
"WHERE " + fieldName + " LIKE '%' + #Find + '%' ";
private DataTable ExecuteDynamic(string TableName,string FieldName, string Find)
{
string sqlSelect = "SELECT * FROM " + TableName +
" WHERE " + FieldName + " LIKE '%'" + Find + "'%' ";
using (connection = new SqlConnection(Strcon))
connection.Open();
{
using (cmd = new SqlCommand(sqlSelect, connection))
{
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 60;
adpt = new SqlDataAdapter(cmd);
dt = new DataTable();
adpt.Fill(dt);
return (dt);
}
}
}

Categories