Object reference not set to an instance of an object ERROR - asp.net

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.

Related

Not running query even tho Im sending the values in ASP

Im running an update query, it says it is not finding the second parameter (status), although I am clearly sending it. They are in different classes and are being called by a button which sends a mail and then changes the value of a variable (statusRef) in the main table (this field is new).
protected void sendMail(object sender, EventArgs e)
{
BO.Messages mail = new BO.Messages();
string body = "Cuerpo Mensaje";
string title = "Titulo";
string script = "alert(\"An email has been sent to the candidate! \");";
mail.refEmail(emailCandi.Text,title,body);
ScriptManager.RegisterStartupScript(this, GetType(),
"ServerControlScript", script, true);
Email_Sent.Visible = true;
changeRefStatus(Int32.Parse(idCand.Text), "1");
}
protected void changeRefStatus(int id, string status)
{
ASF.HC.JobApplication.BO.User u = new ASF.HC.JobApplication.BO.User();
u.saveStatusRef(id,status);
}
public int saveStatusRef(int id, string status)
{
Entity.User u = new Entity.User();
SqlCommand comando = new SqlCommand("dbo.[user_saveStatusRef]", base.Db);
SqlParameter spSearch = new SqlParameter("#id", System.Data.SqlDbType.Int);
SqlParameter spSearch2 = new SqlParameter("#status", System.Data.SqlDbType.VarChar);
spSearch.Value = id;
spSearch.Value = status;
comando.Parameters.Add(spSearch);
comando.Parameters.Add(spSearch2);
return base.ExecuteScalar(comando);
}
The stored procedure...
ALTER PROCEDURE dbo.user_saveStatusRef
#id int,
#status varchar(5)
AS
UPDATE tbl_user
set statusRef = #status
WHERE id = #id
Maybe a typo but you dont assign Value to spSearch2
spSearch.Value = id;
spSearch.Value = status;

Created class is not appearing in other class files asp.net/visual basic

Very basic explanation: I have created a "User" class in a ConnectionClass.cs file and need to use it elsewhere (see below, it's a login button).
The code I'm trying to type is: `
namespace Vehicle_Website.Pages.Account
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnLogin_Click(object sender, EventArgs e)
{
User user = ConnectionClass.LoginUser(txtLogin.Text, txtPassword.Text);
if (user != null)
{
//Store login variables to session
Session["login"] = user.Name;
Session["type"] = user.Type;
Response.Redirect("~/Pages/Home.aspx");
}
else
{
lblError.Text = "Login Failed";
}
}
}
}`
The "User" should be highlighting in "blue" if you like, recognizing that it's an already created class elsewhere, except is isn't and I' getting an error
"type or namespace "User" could not be found"
The exact same applies to the "ConnectionClass" line.. It should be highlighting but again says not recognized.
I have created a public class User and a public static User LoginUser(string login, string password) elsewhere and they work fine without errors. I cant understand why, in plain English, the words "User" and "ConnectionClass" are not "highlighting/changing colour" and being recognised.
I have tried changing properties to compile but seems to have done nothing.
Whatever other information you need I'll be happy to share.
UPDATE***
This is my ConnectionClass.cs file (which is working fine):
namespace Vehicle_Website.App_Code
{
public static class ConnectionClass
{
private static SqlConnection conn;
private static SqlCommand command;
static ConnectionClass()
{
string connectionString = ConfigurationManager.ConnectionStrings["DataConnection"].ToString();
conn = new SqlConnection(connectionString);
command = new SqlCommand("", conn);
}
public static User LoginUser(string login, string password)
{
//Check if user exists
string query = string.Format("SELECT COUNT (*) FROM WebsiteDB.dbo.users WHERE name = '{0}'", login);
command.CommandText = query;
try
{
conn.Open();
int amountOfUsers = (int)command.ExecuteScalar();
if(amountOfUsers == 1)
{
//User exists, check if passwords match
query = string.Format("SELECT password FROM users WHERE name = '{0}'", login);
command.CommandText = query;
string dbPassword = command.ExecuteScalar().ToString();
if(dbPassword == password)
{
//Passwords match, retrieve further information.
query = string.Format("SELECT email, user_type FROM users WHERE name = '{0}'", login);
command.CommandText = query;
SqlDataReader reader = command.ExecuteReader();
User user = null;
while (reader.Read())
{
string email = reader.GetString(0);
string type = reader.GetString(1);
user = new User(login, password, email, type);
}
return user;
}
else
{
//Passwords do not match.
return null;
}
}
else
{
//User exists
return null;
}
}
finally
{
conn.Close();
}
}
}
}
UPDATE
So i think i may have found the problem but no idea how to fix:
Basically my login.aspx.cs page isnt being "linked" to my ConnectionClass.cs
By this, i mean, I have created the below line on the login.aspx.cs page :
Session["login"] = user.Name;
When i try and use ".Name" on my ConnectionClass.cs file, it isnt recognised :
user.Name);
Any idea on how to ensure both pages are communicating? I have tried correcting the namespace so they both match with no luck...
Do you have your ConnectionClass in the same project as the login button? If not you have to add a reference to the project that contains the ConnectionClass.
Also, is your ConnectionClass static? If it is not you will not be able to use it without creating first an instance of a class like this:
ConnectionClass myClass = new ConnectionClass();
User user = myClass.LoginUser(txtLogin.Text, txtPassword.Text);
You have to use full name of the class . That is ConnectedClass.User when accessing the nested class. By default nested class is private so also make sure you are using the correct access modifier
See to that the namespace Vehicle_Website.App_Code is included
in the aspx.cs which contains the button click method
Clearly see this line
public static class ConnectionClass
As per the code it is a static class and also see this constructor!
static ConnectionClass()
{
string connectionString = ConfigurationManager.ConnectionStrings["DataConnection"].ToString();
conn = new SqlConnection(connectionString);
command = new SqlCommand("", conn);
}
When is the constructor called during instanciating an object. Is
it possible instanciate the ConnectionClass? As per OOPs
programming concepts, you cannot do it. Then how will the connection
string and command will be assigned!!
Try fixing this first.

Unable to connect to .MDB database with ASP.NET C#

I'm trying to create a simple user registration system using ASP.NET C# and an MS Access .mdb database. The problem is, whenever I attempt to register, the code fails at the OleDbCommand in the "try" and gets "caught" instead. I have used breakpoints in MS Visual Studio 2012 and all keys are present as far as I can tell. My code follows:
Here is my class where the registration method is located:
public static class DbUtil
{
private static OleDbConnection openConnection()
{
OleDbConnection con = new OleDbConnection();
try
{
string conString = #"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|MainDatabase.mdb";
con = new OleDbConnection(conString);
con.Open();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return con;
}
private static void closeConnection(OleDbConnection con)
{
try
{
con.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public static bool registerUser(string email, string password)
{
try
{
using (OleDbConnection con = openConnection())
{
string sqlString = #"INSERT INTO Users (Email, Password) VALUES (?, ?)";
using (OleDbCommand command = new OleDbCommand(sqlString, con))
{
command.Parameters.AddWithValue("Email", email);
command.Parameters.AddWithValue("Password", password);
command.ExecuteNonQuery();
closeConnection(con);
return true;
}
}
}
catch
{
return false;
}
}
}
Here is where the method is called:
public void btnRegisterSubmit_Click(object sender, EventArgs e)
{
string strEmail = txtRegisterEmail.Text;
string strPassword = txtRegisterPassword.Text;
bool regSuccess = DbUtil.registerUser(strEmail, strPassword);
if (regSuccess == false)
{
Response.Redirect("Default.aspx?reg=fail");
}
else
{
if (regSuccess == true)
{
Response.Redirect("Default.aspx?reg=success");
}
else
{
Response.Redirect("Default.aspx?reg=error");
}
}
}
I'm currently using the praised parameter method, for the first time. I did use a simple concatenation method in the SQL string, but this yielded the same problem.
Also, there are no errors printed or exceptions thrown.
Any help at all would be highly appreciated. Thanks in advance!
UPDATE:
Exception:
System.Data.OleDb.OleDbException (0x80040E14): Syntax error in INSERT INTO statement. 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 DbUtil.registerUser(String email, String password) in c:\Users\******\Documents\Visual Studio 2012\WebSites\********************\App_Code\DbUtil.cs:line 51
I'm not using any reserved words
password is indeed a reserved word in Access SQL. The following code fails with
OleDbException was unhandled: Syntax error in INSERT INTO statement.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
namespace oledbTest1
{
class Program
{
static void Main(string[] args)
{
using (var conn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\__tmp\testData.accdb;"))
{
conn.Open();
using (var cmd = new OleDbCommand(
#"INSERT INTO Users (Email, Password) VALUES (?, ?)",
conn))
{
cmd.Parameters.AddWithValue("?", "gord#example.com");
cmd.Parameters.AddWithValue("?", "myPassword");
cmd.ExecuteNonQuery();
}
conn.Close();
}
Console.WriteLine("Done.");
Console.ReadKey();
}
}
}
If I change the code to...
...
using (var cmd = new OleDbCommand(
#"INSERT INTO Users (Email, [Password]) VALUES (?, ?)",
conn))
{
...
...then it works fine.
Managed to get this fixed. I rewrote the registerUser() method, and removed the using blocks and it now works great. Here's the code with the removed parts commented:
public static bool registerUser(string email, string password)
{
try
{
//using (OleDbConnection con = openConnection())
//{
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OleDb.4.0;Data Source=|DataDirectory|MainDatabase.mdb");
string sqlString = "INSERT INTO [Users] ([Email], [Password]) VALUES (#Email, #Password)";
//using (OleDbCommand command = new OleDbCommand(sqlString, con))
//{
OleDbCommand command = new OleDbCommand(sqlString, con);
command.Parameters.AddWithValue("#Email", email);
command.Parameters.AddWithValue("#Password", password);
con.Open();
command.ExecuteNonQuery();
con.Close();
return true;
//}
//}
}
catch (Exception e)
{
return false;
//System.Diagnostics.Debug.WriteLine(e.Message);
}
}
Thanks for the comments :)

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.

Question about inserting Users/Members into a database table!

My registration form has got a CreateUserWizard. I used its event that is fired after the user is created.
Then I obtain the users identity and key. In the last line, I send the unique key to a function inside a class that should insert the key into the Users table (the field is a primary key and is unique).
public partial class Registration : System.Web.UI.Page
{
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
MembershipUser CurrentUser = Membership.GetUser(User.Identity.Name);
int i =(int) CurrentUser.ProviderUserKey;
RegisterAdo.InsertUsers(i);
}
}
Below, I execute the query with the value that I passed and insert the user into a database
class RegisterAdo
{
public static void InsertUsers(int UsersIDentity)
{
string myConnectionString = WebConfigurationManager.ConnectionStrings["YourGuruDB"].ConnectionString;
SqlConnection sqlConnect = new SqlConnection(myConnectionString);
SqlCommand sqlCommand = new SqlCommand(RegisterAdo.insertCommand(UsersIDentity), sqlConnect);
try
{
sqlConnect.Open();
sqlCommand.ExecuteNonQuery();
}
catch (Exception x)
{
}
finally
{
sqlConnect.Close();
}
}
public static String insertCommand(int UsersIdentityToinsert)
{
string insertCommand="INSERT INTO Users(";
insertCommand += "UserID)";
insertCommand += "VALUES('";
insertCommand += UsersIdentityToinsert+"')";
return insertCommand;
}
My question is whether it is the best way to insert UserID into a table, and whether I do it right at all. I need the UserID to be unique, and the whole command executed with no fail...(just after the user was created and the whole UserCreateUser finished validating the user!!!
I would change two things mainly:
don't concatenate together your SQL statement - this opens doors to SQL injection attacks. Use parametrized queries instead - they are both safer, and they perform better (since only a single copy of the query's execution plan needs to be created and cached and will be reused over and over again)
put your SqlConnection and SqlCommand objects into using blocks so that they'll be automatically freed / disposed when the using blocks ends (and you can save yourself the finally block of the try...catch construct, too!).
So my code would look like this
public static void InsertUsers(int UsersIDentity)
{
string myConnectionString = WebConfigurationManager.ConnectionStrings["YourGuruDB"].ConnectionString;
string insertStmt =
"INSERT INTO dbo.Users(UserID) VALUES(#UserID)";
using(SqlConnection _con = new SqlConnection(myConnectionString))
using(SqlCommand _cmd = new SqlCommand(insertStmt, sqlConnect))
{
_cmd.Parameters.Add("#UserID", SqlDbType.Int).Value = UsersIDentity;
try
{
_con.Open();
_cmd.ExecuteNonQuery();
_con.Close();
}
catch (Exception x)
{
// do something if error occurs
}
}

Resources