Npgsql.NpgsqlException: ERROR: 42601: syntax error at or near "where" - asp.net

I have the followinf web service in asp.net
//setup profile
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void SetProfile(string userName, string firstName, string lastName, string imageUrl)
{
//create and open connection
NpgsqlConnection profileConnection = new NpgsqlConnection(ConfigurationManager.ConnectionStrings["PrevueConnString"].ToString());
profileConnection.Open();
//create query and command
string query = "INSERT into \"Users\" (\"FirstName\", \"LastName\", \"ImageUrl\") values(:fname, :lname, :imageUrl) where \"UserName\" = :user";
NpgsqlCommand profileCommand = new NpgsqlCommand(query, profileConnection);
profileCommand.Parameters.Add(new NpgsqlParameter("user", DbType.String));
profileCommand.Parameters.Add(new NpgsqlParameter("fname", DbType.String));
profileCommand.Parameters.Add(new NpgsqlParameter("lname", DbType.String));
profileCommand.Parameters.Add(new NpgsqlParameter("imageUrl", DbType.String));
profileCommand.Parameters[0].Value = userName;
profileCommand.Parameters[1].Value = firstName;
profileCommand.Parameters[2].Value = lastName;
profileCommand.Parameters[3].Value = imageUrl;
int result = profileCommand.ExecuteNonQuery();
profileCommand.Dispose();
profileConnection.Close();
string json = new JavaScriptSerializer().Serialize(result);
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.Flush();
Context.Response.Write(json);
}
On invoking the web service, I get the following error:
Npgsql.NpgsqlException: ERROR: 42601: syntax error at or near "where"

I guess i figured out the error, i used the 'Where' clause with an Insert command, changed that to Update and things are smooth now... :) Appreciate your help..!!

Related

Sqllite SQLiteDataReader returns enpty reader while SQLiteDataAdapter returns the right result

I have trouble with Sqllite SQLiteDataReader. Using the same connection string and the same sql statement SQLiteDataReader returns empty reader while SQLiteDataAdapter returns suspected record.
I this case I try to get the record with the highest value in the Id field.
The database contains several records with unique values in the Id field, but the reader return is empty when using SQLiteDataReader. When I use the same connection string and sql statement with SQLiteDataAdapter suspected results appears. I supply a part of the static class I use for communication with the database. The method SenasteBokning using SQLiteDataReader isn’t working. The method SenasteBokning2 using SQLiteDataAdapter works perfect.
What’s wrong with the method SenasteBokning?
I use:
Windows 10
Visual Studio 2017
.net framework 4.5.2 (Was default at creation of Windows Forms application)
Nuget package System.Data.SQLite.Core 1.0.108
static class Databas
{
private static string appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
private static string dbPath = #"\BokningarConvention.db";
private static string connectionString = "Data Source= " + appPath + dbPath;
private static SQLiteConnection con;
private static SQLiteCommand cmd;
private static SQLiteDataReader reader;
private static SQLiteDataAdapter adapter;
private static SQLiteCommandBuilder commandBuilder;
private static DataTable table;
private static string senaste = "SELECT Nummer, NrSammaDag, Datum FROM Bekraftelser WHERE Id = (SELECT MAX (Id) FROM Bekraftelser)";
// This don't work
public static Bokning SenasteBokning()
{
Bokning bokning = new Bokning();
using (SQLiteConnection con2 = new SQLiteConnection(connectionString))
{
con2.Open();
SQLiteCommand cmd2 = new SQLiteCommand(senaste, con2);
SQLiteDataReader reader2 = cmd2.ExecuteReader();
// Here the reader is empty
while (reader2.Read())
{
// Error at first read
// should handle results the same way as in SenasteBokning2
// removed during testing
}
}
return bokning;
}
//This works perfekt
public static Bokning SenasteBokning2()
{
Bokning bokning = new Bokning();
using (SQLiteConnection db = new SQLiteConnection(connectionString))
{
adapter = new SQLiteDataAdapter(senaste, connectionString);
commandBuilder = new SQLiteCommandBuilder(adapter);
table = new DataTable();
db.Open();
adapter.Fill(table);
foreach (DataRow row in table.Rows)
{
int nummer;
int samma;
DateTime datum;
nummer = (int)((long)row["Nummer"]);
datum = Verktyg.FromDateInteger((int)((long)row["Datum"]));
if (!row.IsNull("NrSammaDag"))
{
samma = (int)((long)row["NrSammaDag"]);
bokning = new Bokning(nummer, samma, datum);
}
else
{
bokning = new Bokning(nummer, datum);
}
}
}
return bokning;
}
}

Secure website from SQL Injection ' using ASP.net and an Access database

I currently have a website with a normal registration and login, coded with ASP.net.
I am using an Access database, while using a C# class my friend wrote for handling most of the database actions (executeQuery, executeRead, isExits...).
Now that I've almost finished building my website, I want to start adding security - mostly to my database. I have searched for a while now for a tutorial on the subject, but I could not find anything good exept an old microsoft msdn article which I couldn't realy get its code to work.
The furthest I've got now is just no allowing any dangerous characters in the username and password, (such as ',--,;), but it kind of feels as if it is the worse solution that i can use (why shouldn't my users use this characters?).
I think that the best solution I've found is somehow insertion the variables into the query string after declaring it (something to do with "WHERE username=#user" or something like that), but i couldn't get it to work with Access and with my oleDBManager.
here is my current registration code. handle() is removing all ' from the string, and Validate() checks for dangerous parts in the string.
string username = user.Text;
string password = pass.Text;
bool isThingy = false;
if (handle(ref password)) isThingy = true;
if (handle(ref username)) isThingy = true;
if (username != "" && username != null)
{
if (password != "" && password != null)
{
if (Validate(username, password))
{
if ((db.IsExist("SELECT * FROM Table1 WHERE username='" + username + "'") == false))
{
int a = db.ExecuteQuery("INSERT INTO `Table1`(`username`, `password`, `logins`, `email`, `fname`, `lname`, `country`, `city`, `birthday`, `userid`) VALUES ('" + username + "', '" + password + "', '0', '', '', '', '', '', '', '" + Convert.ToString(Convert.ToInt32(db.ExecuteCellRead("SELECT MAX(userid) FROM Table1")) + 1) + "');");
if (!isThingy) errorLabel.Text = "Your user has been successfully registered";
else errorLabel.Text = "The ' token is invalid. your user was registered absence the '.";
}
else
errorLabel.Text = "This username is already taken";
}
else errorLabel.Text = "Invalid name format";
}
else errorLabel.Text = "Please enter a password";
}
else errorLabel.Text = "Please enter a user name";
as for the oleDBManager (named db in my code):
private OleDbConnection link; // The link instance
private OleDbCommand command; // The command object
private OleDbDataReader dataReader; // The data reader object
private OleDbDataAdapter dataAdapter; // the data adapter object
private DataTable dataTable; // the data table object
private string dbName; // the Database filename
private int version; // the usersTableG office version
private string connectionString; // the connection string for the database connection
private string provider; // the matching driver string for the connection string
private string path; // the path to the database file
...
public int ExecuteQuery(string query)
{
this.link.Open();
int rowsAffected;
// ---
this.command = new OleDbCommand(query, this.link);
try
{
rowsAffected = this.command.ExecuteNonQuery();
}
catch (InvalidOperationException e)
{
if (e.Data == null)
throw;
else
rowsAffected = -1;
}
finally
{
this.command.Dispose();
this.link.Close();
}
// ---
return rowsAffected;
}
public bool IsExist(string query)
{
this.link.Open();
// ---
this.command = new OleDbCommand(query, this.link);
this.dataReader = this.command.ExecuteReader();
bool a = this.dataReader.Read();
// ---
this.command.Dispose();
this.link.Close();
// ---
return a;
}
public string ExecuteCellRead(string query)
{
string output = "";
this.dataTable = this.ExcecuteRead(query);
foreach (DataRow row in this.dataTable.Rows)
{
foreach (object obj in row.ItemArray)
{
output += obj.ToString();
}
}
return output;
}
So, as you might see, the main problem is that the user now can not use characters as '.
It suppose the best solution would be using the # variables in the SQL queries, but I have no idea how.
[thanks for your help]
PS. i HAVE changed my tables' name ;)
edit: most of you are telling me to use these parameterized queries, but it would be great if you could give me an example of how to use them, since i've never done that
So, thanks to #Remou, my FINAL code is:
db.DoWeirdStackOverFlowStuff(
"INSERT INTO `Table1`(`username`, `password`, `logins`) VALUES (#username, #password, '0');"
, new string[] { "#username", "#password" }
, new string[] { username, password });
and
public int DoWeirdStackOverFlowStuff(string query, string[] vars, string[] reps)
{
this.link.Open();
int rowsAffected;
// ---
this.command = new OleDbCommand();
this.command.CommandText = query;
this.command.CommandType = System.Data.CommandType.Text;
this.command.Connection = this.link;
//Parameters in the order in which they appear in the query
for (int i = 0; i < vars.Length; i++)
this.command.Parameters.AddWithValue(vars[i], reps[i]);
try
{
rowsAffected = this.command.ExecuteNonQuery();
}
catch (InvalidOperationException e)
{
if (e.Data == null)
throw;
else
rowsAffected = -1;
}
finally
{
this.command.Dispose();
this.link.Close();
}
// ---
return rowsAffected;
}
for whoever needs this =]
Some notes
In MS Access, I have a saved query called UpdateUser, it looks like this:
UPDATE INTERNETSETTINGS
SET url = [#url],
databasename = [#databasename],
port = [#port],
username = [#username],
[password] = [#password]
I can refer to this query by name in my code, using a command object:
OleDbCommand Command = new OleDbCommand();
Command.CommandText = "UpdateUser"; //saved query
Command.CommandType = System.Data.CommandType.StoredProcedure;
Command.Connection = cn; //a connection to the database
//Parameters in the order in which they appear in the query
Command.Parameters.AddWithValue("#url", "a"); //a,b,c etc for my test run
Command.Parameters.AddWithValue("#databasename", "b");
Command.Parameters.AddWithValue("#port","c");
Command.Parameters.AddWithValue("#username", "d");
Command.Parameters.AddWithValue("#password", "e");
Command.ExecuteNonQuery();
I don't remember whether Access does the same thing as SQL Server here, but in SQL Server you can escape the single quote mark by doubling it:
username = username.Replace("'", "''");
So you can include single-quote marks in the string, you can store them in the database, and they can't be used as malicious string terminators.

Sql to update table

I am using the following code to update the user information but i am getting error. Can anybody point me out what is wrong. I am writing this code for web service.
public string UpdateUser(int uID, string fName,
string lName, string password, string emailAddress)
{
// Create connection object
int ix = 0;
string rTurn = "";
OleDbConnection oleConn = new OleDbConnection(connString);
try
{
oleConn.Open();
string sql = "UPDATE [User] SET [fName]=#fName, [lName]=#lName, [password]=#password, [emailAddress]=#emailAddress" + "WHERE [ID]=#uID";
OleDbCommand oleComm = new OleDbCommand(sql, oleConn);
oleComm.Parameters.Add("#fName", OleDbType.Char).Value = fName;
oleComm.Parameters.Add("#lName", OleDbType.Char).Value = lName;
oleComm.Parameters.Add("#password", OleDbType.Char).Value = password;
oleComm.Parameters.Add("#emailAddress", OleDbType.Char).Value = emailAddress;
oleComm.Parameters.Add("#uID", OleDbType.Integer).Value = uID;
ix = oleComm.ExecuteNonQuery();
if (ix > 0)
rTurn = "User Updated";
else
rTurn = "Update Failed";
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
rTurn = ex.ToString();
}
finally
{
oleConn.Close();
}
return rTurn;
}
Error
*I am getting following error when i try to update user.*
<string>
System.Data.OleDb.OleDbException: Syntax error (missing operator) in query expression '#emailAddressWHERE [ID]=#uID'.
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteNonQuery()
at UserManagement.UserRegistration.UpdateUser(Int32 uID, String fName, String lName, String password, String emailAddress) in C:\Users\smartamrit\Desktop\SystemSoftware\UserManagement\UserRegistration.asmx.cs:line 97
</string>
you need to add extra space before WHERE
string sql = #"UPDATE [User]
SET [fName]=#fName,
[lName]=#lName, [password]=#password,
[emailAddress]=#emailAddress" + " WHERE [ID]=#uID";
^ here
or I can't see any difference if you didn't concatenate it, why not do it directly
string sql = #"UPDATE [User]
SET [fName]=#fName,
[lName]=#lName,
[password]=#password,
[emailAddress]=#emailAddress
WHERE [ID]=#uID";
The error is pretty self-explanatory:
'#emailAddressWHERE [ID]=#uID'
You have no space between #emailAddress and WHERE
You need a space before the WHERE here
#emailAddress" + " WHERE
You need add space before your where starts.
You can write your query like this as mentioned below.
string sql = "UPDATE [User] SET [fName]=#fName, [lName]=#lName,
[password]=#password, [emailAddress]=#emailAddress" +" "+ "WHERE [ID]=#uID";

Object reference not set to an instance of an object ERROR

I have few textboxes whose values are to be inserted into SQl table on Submit button click. But it gives me "Object reference not set to an instance of an object" Exception. Below is the code I have written for this. Please do help me in this.
contact_new.aspx.cs
protected void btnSubmit_Click(object sender, EventArgs e)
{
DateTime dtime;
dtime = DateTime.Now;
string ocode = offercode.Text;
string firstname = firstnamepreapp.Text;
string lastname = lastnamepreapp.Text;
string email = emailpreapp.Text;
string phoneno = phonepreapp.Text;
string timetocall = besttimepreapp.SelectedItem.Value;
string time = dtime.ToString();
//Insert the data into autoprequal table
<--- GIVES ME AN ERROR ON THIS LINE --->
Insert.insertINTOautoprequal(ocode, time, firstname, lastname, email, phoneno, timetocall);
}
Insert.cs (App_code class)
namespace InsertDataAccess
{
public class Insert
{
public Insert()
{
//
// TODO: Add constructor logic here
//
}
public static bool insertINTOautoprequal(string code, string time, string first, string last, string email, string phoneno, string timetocall)
{
bool success = false;
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connstring"].ConnectionString);
conn.Open();
string query = "Insert INTO autoprequal(offercode, timeofday, firstname, lastname, emailID, phone, besttimetocall) Values(#offercode, #time, #first, #last, #email, #phoneno, #timetocall);";
SqlCommand cmd = new SqlCommand(query, conn);
try
{
cmd.Parameters.AddWithValue("#offercode", code);
cmd.Parameters.AddWithValue("#time", time);
cmd.Parameters.AddWithValue("#first", first);
cmd.Parameters.AddWithValue("#last", last);
cmd.Parameters.AddWithValue("#email", email);
cmd.Parameters.AddWithValue("#phoneno", phoneno);
cmd.Parameters.AddWithValue("#timetocall", timetocall);
if (cmd.ExecuteNonQuery() == 1) success = true;
else success = false;
return success;
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
}
}
Step through the code, as the error is most likely bubbling up from the SQL insert routine. I woulud guess the connection string is not being pulled from the configuration file, but without stepping through that is a wild guess. I would take time to learn how to debug in Visual Studio, as it will help you easily spot what cannot be a problem so you can focus on what is likely to be the problem.

Object reference not set to an instance of an object

I am facing an issue while inserting some items into database in asp.net web service application.
Here is my code ..
public void DoRequestLog(HttpRequest request)
{
string UserAgent = request.Headers["User-Agent"];
string Date = "4/14/2011";//request.Headers["Date"];
string HostIP = request.Headers["Host"];
string URL = request.Headers["Referer"];
string MethodName = request.HttpMethod;
string VersionNo = "";
string IMEINo = "";
string dbString = Configuration.GetDBConnectionString();
SqlConnection DardSqlConnection = new SqlConnection(dbString);
DardSqlConnection.Open();
SqlCommand log = DardSqlConnection.CreateCommand();
log.CommandText = "insert into ConnectionLog values('"+UserAgent+"','"+Date+"','"+HostIP+"','"+URL+"','"+MethodName+"','"+VersionNo+"','"+IMEINo+"');";
log.ExecuteNonQuery();
}
Please Help
Since I am new to .net environment.
Try this:
public void DoRequestLog(HttpRequest request)
{
// We don’t need to log anything if there is no HTTP request.
if (request == null)
return;
string UserAgent = request.Headers["User-Agent"];
string Date = "4/14/2011";//request.Headers["Date"];
...

Resources