Null Reference when connecting to SQL Server database C# ASP.NET [duplicate] - c#

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 4 years ago.
I keep on receiving a null reference when trying to connect to the SQL Server database via Visual Studio 2017. Below is where the reference is and how it is trying to connect to gather the data. Please help! Thank you!.
Profile.aspx
protected void updateProfile(object sender, EventArgs e)
{
// Database entry
string message = "Your information has been updated accoridngly!<br><br>";
double number;
if (txtName.Text.Equals("") || ddlDegree.SelectedValue.Equals("") || txtExperience.Text.Equals("") || !Double.TryParse(txtExperience.Text, out number) || txtSalary.Text.Equals("") || txtStreet.Text.Equals("") || txtCity.Text.Equals("") || txtState.Text.Equals("") || txtZipcode.Text.Equals(""))
{
message += "However:<br>There was an error found in your entry fields, resulting in a failure to store field information. Make sure that all fields are filled and that the Experience field is a double value.";
}
else
{
**myDataLayer.updateStaff(Session["userid"].ToString(), txtName.Text, ddlDegree.SelectedValue, txtExperience.Text, txtSalary.Text, txtStreet.Text, txtCity.Text, txtState.Text, txtZipcode.Text);** - **Null Reference**
}
Here is the data layer class it needs to reference to:
string _ConString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection con;
SqlDataAdapter sda = new SqlDataAdapter();
SqlCommand cmd = new SqlCommand();
SqlDataReader data;
// Handles updating staff info
public bool updateStaff(string userid, string full_name, string degree, string experience, string salary, string street, string city, string state, string zipcode)
{
try
{
con = new SqlConnection(_ConString);
con.Open();
cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "UPDATE staff SET [full_name] = '" + full_name + "', [degree] = '" + degree + "', [experience] = '" + experience + "', [salary] = '" + salary + "', [street] = '" + street + "', [city] = '" + city + "', [state] = '" + state + "', [zipcode] = '" + zipcode + "' WHERE userid = '" + userid + "'";
cmd.ExecuteNonQuery();
con.Close();
return true;
}
catch (OleDbException e)
{
System.Diagnostics.Debug.WriteLine(e.ToString());
}
finally
{
con.Close();
}
return false;
}

Your validations are weak and never go with building sql commands for insert, update, delete without parameterizing them. You are prone for SQL-INJECTION.
First, basic validation. By using IsNullOrWhiteSpace, you are preventing nulls to begin with (hence your error), but also a start for your SQL-Injection.
if( string.IsNulllOrWhiteSpace( txtName.Text )
|| string.IsNullOrWhiteSpace( ddlDegree.SelectedValue )
… )
message back about failed values
Now the SQL. User Parameters. What happens if you have a name O'Connor. The first quote would kill your string single-quote balancing.
cmd.Connection = con;
cmd.CommandText =
#"UPDATE staff SET
full_name = #parmFullName,
degree = #parmDegree,
experience = #parmExperience,
salary = #parmSalary,
street = #parmStreet,
city = #parmCity,
state = #parmState,
zipcode = #parmZIP,
where
userid = #parmUserID";
// pulling the parameters from the parameters you pass to your UpdateStaff() call
cmd.Parameters.AddWithValue( "parmFullName", full_name );
cmd.Parameters.AddWithValue( "parmDegree", degree );
cmd.Parameters.AddWithValue( "parmExperience", experience );
cmd.Parameters.AddWithValue( "parmSalary", salary );
cmd.Parameters.AddWithValue( "parmStreet", street);
cmd.Parameters.AddWithValue( "parmCity", city );
cmd.Parameters.AddWithValue( "parmState", state );
cmd.Parameters.AddWithValue( "parmZIP", zipcode );
cmd.Parameters.AddWithValue( "parmUserID", userid );
So, for the most-part, you should be good. No Null values, no mismatched single-quoted strings. This is not the ultimate in validation, you should definitely read more on SQL-Injection and data cleansing though.
In my example, I explicitly add a prefix "parm" to the parameters to differentiate between the actual VALUES you are trying to work with.
Also, if the data columns are of date, integer, double, string, let them remain the type they are intended. The parameters will pass to through correctly.

Related

C# - Retrieve Largest MySQL Column Value, Increment by 1, and use in INSERT statement

I'm using c#, MySQL and visual studio 2015.
I have a:
Database called 'cp_users'
Table called 'users'
Column called 'account_no'
The account_no column is int(11) and primary key.
I am simply trying to get the value of the highest account number, add 1 to it and then use the new value in my statement to insert the new user data, thereby ensuring that the account numbers never conflict.
For info:
public partial class Form1 : Form
{
MySqlConnection mcon = new MySqlConnection();
public Form1()
{
InitializeComponent();
mcon.ConnectionString = "datasource=166.XXX.XXX.XXX;port=3306;initial catalog=cp_users; username=XXXXXX;password=XXXXXX";
}
Code I'm having trouble with:
if (textBox1.Text != "" && textBox2.Text != "" && textBox3.Text != "" && textBox4.Text != "" && textBox5.Text != "" && textBox6.Text != "" && listBox1.SelectedItem != null)
{
mcon.Open();
//Upload New User Information to 'users' Database
try
{
//CODE TO RECALL LARGEST ACCOUNT NUMBER AS reader3 VALUE,
//INCREASE IT BY 1, ASSIGN IT AS A STRING
//FOR USE BELOW (NOT WORKING)
MySqlCommand mda3 = new MySqlCommand();
mda3.Connection = mcon;
mda3.CommandText = "SELECT max(account_no) value FROM users";
MySqlDataReader reader3 = mda3.ExecuteReader();
reader3 = reader3++;
//UPLOAD NEW USER DATA INCLUDING 'reader3' VALUE FOR 'account_no'
MySqlCommand mda2 = new MySqlCommand();
mda2.Connection = mcon;
mda2.CommandText = ("insert into cp_users.users(account_no, first_name, last_name, email_1, company_industry, user_password) values('" + reader3 + "','" + textBox1.Text + "', '" + textBox2.Text + "', '" + textBox3.Text + "', '" + listBox1.Text + "', '" + textBox5.Text + "');");
MySqlDataReader reader2 = mda2.ExecuteReader();
mcon.Close();
this.Hide();
Form2 frm4 = new Form2();
frm4.ShowDialog();
MessageBox.Show("Registration Successful - You can now login to our Desktop, Web and App Interfaces", "Welcome to ConnectPlanet");
}
catch
{
MessageBox.Show("New Registration Failed - We're Sorry, Please Contact Customer Support", "Oops!");
mcon.Close();
}
Any advice is appreciated, I'm guessing this is simple for someone with more experience but I cant seem to find the answer online or in my (Small) book collection.
You're looking for a AUTO_INCREMENT column. see :Using AUTO_INCREMENT
CREATE TABLE users
(
account_no INT NOT NULL AUTO_INCREMENT,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
email_1 VARCHAR(100) NOT NULL,
company_industry VARCHAR(100) NOT NULL,
user_password VARCHAR(128) NOT NUL
);
So you don't even need to specify the id column when inserting data :
insert into cp_users.users(first_name, last_name, email_1, company_industry, user_password) values( ....

Making a reservation button

I'm making a class reservation website and having trouble with creating the button.
I would like to customer to insert two details session into two textboxes, session type "class" or "workshop" and date & time and they will be able to see that information from the DataGridView displayed.
Once they hit the "Reserve" button the button will run a query where it'll add the chosen session from Session table to Reservation table. However my code executes with no errors but does not update the "Reservation" table.
here's my code:
OleDbConnection myConnection = GetConnection();
OleDbCommand cmd = myConnection.CreateCommand();
string query = "select COUNT(*) from [Yoga-Session] where [session type] = '" + txt_type.Text + "' and duration = '" + txt_datetime.Text + "';";
OleDbCommand command = new OleDbCommand(query, myConnection);
myConnection.Open();
int rows1 = (Int32)command.ExecuteScalar();
if (rows1 >= 1)
{
cmd = new OleDbCommand("Select session_id from [yoga-session] where [session type] = '" + txt_type.Text + "' and duration = '" + txt_datetime.Text +"';",myConnection);
int classId = (Int32)command.ExecuteScalar();
cmd = new OleDbCommand("select client_id from client where name = '" + Session["[name]"] + "';", myConnection);
int clientID = (Int32)command.ExecuteScalar();
string query1 = "insert into reservation (session_id, client_id, client_name) values ('" + classId + "','" + clientID + "','" + Session["[name]"].ToString() + "');";
cmd = new OleDbCommand(query1, myConnection);
cmd.ExecuteNonQuery();
Response.Write("Reservation successful");
Response.Redirect("reservation.aspx");
myConnection.Close();
}
}
}
int classId = (Int32)cmd.ExecuteNonQuery();
int clientID = (Int32)cmd.ExecuteNonQuery();
You need to use cmd.ExecuteScalar() to get session_id and client_id values. ExecuteNonQuery returns you no of rows affected by the SQL query.
Also see what #Sherantha pointed out.
ExecuteNonQuery() is not for SELECT commands. To get a field value from SELECT command we need to use ExecuteScalar().
Try replacing;
int rows1 = (Int32)command.ExecuteScalar();
Just a small headsup before I compose my real answer (because I don't have rep to comment)
Firstly: Use Prepared Statements. They help immensely in reducing errors from typing SQL queries, as well as a way to prevent SQL Injection Attacks in real-world situations.
Secondly: While not really needed in most database types, it is recommended that a naming convention is strictly uniform in your code.
Well aside from that, I will get to the real answer now.
Looking at the code, I am assuming that classID and clientID are integers, but in your code, it looks like they are parsed as strings due to the ' ' characters. Do not use the characters when inserting integers.
EDIT: is [session type] meant to be [session_type]?
You should use query1 instead of query.
string query1 = "insert into reservation (session_id, client_id, client_name) values ('" + classId + "','" + clientID + "','" + Session["[name]"].ToString() + "');";
cmd = new OleDbCommand(query1, myConnection);// not query but query1
cmd.ExecuteNonQuery();
Response.Write("Reservation successful");
PS: Use sql data reader to select data.
cmd = new OleDbCommand("Select session_id from [yoga-session] where [session type] = '" + txt_type.Text + "' and duration = '" + txt_datetime.Text +"';",myConnection);
SqlDataReader rdr = cmd.ExecuteReader();
int classId = 0;
while (rdr.Read())
{
clientID = Convert.ToInt32(rdr["session_id"]);
}

How to UPDATE multiple times off one connection OleDb

I am trying to update an Access database with information I have passed to a [WebMethod] from multiple txtbox's on a website.
[WebMethod]
public string changePersonalInfo(string email, string name, string id, string address, string contactDetails, string password, string question, string answer, string loggedInEmail)
I am passing all information to it weather it has a value or not.
if (email != "") //Wont execute if there is no value
{
cmd.CommandText = #"UPDATE BuyerInfo SET [emailAddress] = '" + email + "' WHERE (emailAddress = '" + loggedInEmail + "')";
}
if (name != "")
{
cmd.CommandText = #"UPDATE BuyerInfo SET [name] = '" + name + "' WHERE (emailAddress = '" + loggedInEmail + "')";
}
if (id != "")
{
cmd.CommandText = #"UPDATE BuyerInfo SET [id] = '" + id + "' WHERE (emailAddress = '" + loggedInEmail + "')";
}
//etc. It goes on for a few more.
cmd.ExecuteNonQuery();
conn.Close();
The problem is when I run the website it only updates the data from the last txtbox on the website (so in other words the last variable that has a value). How do I fix this, or if there is maybe a better way to do it.
P.S Keep in mind I am new to Web Services.
Thanx

Insert to a SQL Server CE database

How do you insert into a table in a .sdf database?
I've tried the following:
string connection = #"Data Source=|DataDirectory|\InvoiceDatabase.sdf";
SqlCeConnection cn = new SqlCeConnection(connection);
try
{
cn.Open();
}
catch (SqlCeException ex)
{
MessageBox.Show("Connection failed");
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.ExitThread();
}
string clientName = txt_ClientName.Text;
string address = txt_ClientAddress.Text;
string postcode = txt_postcode.Text;
string telNo = txt_TelNo.Text;
string sqlquery = ("INSERT INTO Client (Name,Address,Postcode,Telephone_Number)Values(" + clientName + "','" + address + "','" + postcode + "','" + telNo + ")");
SqlCeCommand cmd = new SqlCeCommand(sqlquery, cn);
try {
int affectedRows = cmd.ExecuteNonQuery();
if (affectedRows > 0)
{
txt_ClientAddress.Text = "";
txt_ClientName.Text = "";
txt_postcode.Text = "";
txt_TelNo.Text = "";
MessageBox.Show("Client: " + clientName + " added to database. WOoo");
}
}
catch(Exception){
MessageBox.Show("Insert Failed.");
}
But it doesn't seem to matter what i do it just shows "Insert Failed".
Thanks in advance.
You forgot opening quotation mark on the first value.
Values(" + clientName + "','"
change to:
Values('" + clientName + "','"
But this is generally a bad way to build query. Use parametrized query instead.
See: http://msdn.microsoft.com/en-us/library/system.data.sqlserverce.sqlcecommand.parameters(v=vs.80).aspx
catch(Exception ex)
{
MessageBox.Show(ex);
}
Will give you more info on error.
It is the same old story. When you build a sql command concatenating string these kinds of errors abund. And the simple syntax problem is not the worst. The Sql Injection is the most dangerous one.
Please build your query in this way
string sqlquery = ("INSERT INTO Client (Name,Address,Postcode,Telephone_Number)" +
"Values(#client,#address, #postcode, #tel)";
SqlCeCommand cmd = new SqlCeCommand(sqlquery, cn);
cmd.Parameters.AddWithValue("#client", clientName);
cmd.Parameters.AddWithValue("#address", address);
cmd.Parameters.AddWithValue("#postcode", postcode);
cmd.Parameters.AddWithValue("#tel", telNo);
cmd.ExecuteNonQuery();
As others have already said your syntax error is caused by omitting the initial single quote. But you could have other errors. For example, what about a client called O'Hara?. Now you have a single quote inside the clientname and this wreak havoc your string concatenation.
Instead a parameter will be accurately parsed and every problematic character found will be treated appropriately (in this case doubling the single quote)
Your SQL statement is incorrect.
string sqlquery = ("INSERT INTO Client (Name,Address,Postcode,Telephone_Number)Values('" + clientName + "','" + address + "','" + postcode + "','" + telNo + "')");
Take this. You forgot the ' at the beginning and the end of the values
To insert data into Sql, data type should be considered. If you insert a string value (varchar) you have to surround it by single quotation, like '"+full_Name+"', but integer type doesn't need this. example
string myQuery = "INSERT INTO Persons (phone, fullname) VALUES ("+telNo+",'"+full_Name+"')";
where full name is string variable and phone number is only number.

Implementing database search

I use mysql as database where I store my data.
I have a windows form with textboxes radiobuttons, comboboxes and more; where people give personal information about themselves like (first name, last name, sex, date birthday, phone, father name and more like this). (40 fields total)
I want to do a search button. With this button I want to fill some fields and after I push the search button a new window be opened containing all people with same personal information. I achieved to do a search button for one field (for example searching only by name).
But I have a problem when I select to search with more than one fields. For example I select to search all people who have name:Chris, Nickname:Dung, sex:Male, Birth_Country:UK and other but when I push search it gives back a window with irrelevant with the search data. Can someone help me with that?
The code I made for the search button after changes is:
public MySqlDataAdapter da;
public DataSet ds;
public string sTable = "data";
private void anazitisi_button_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
try
{
conn = openconnectio.GetConn();
string radiob = null;
if (radioButton1.Checked == true)
{
radiob = radioButton1.Text;
}
else if(radioButton2.Checked == true)
{
radiob = radioButton2.Text;
}
StringBuilder Query = new StringBuilder("SELECT * FROM data d INNER JOIN country c ON d.id_data = c.id_country WHERE 1=1 ");
if (!String.IsNullOrEmpty(textBox1.Text))
Query.Append(" AND name like '" + textBox1.Text + "'");
if (!String.IsNullOrEmpty(textBox2.Text))
Query.Append(" AND lastname like '" + textBox2.Text + "'");
if (!String.IsNullOrEmpty(radiob))
Query.Append(" AND sex like '" + radiob + "'");
if (!String.IsNullOrEmpty(maskedTextBox1.Text))
Query.Append(" AND birthdate like '" + maskedTextBox1.Text + "'");
if (!String.IsNullOrEmpty(maskedTextBox2.Text))
Query.Append(" AND phone_number like '" + maskedTextBox2.Text + "'");
MySqlDataAdapter da = new MySqlDataAdapter(Query.ToString(), conn);
ds = new DataSet();
da.Fill(ds, sTable);
conn.Close();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
DataGridView dg1 = new DataGridView();
form2.Controls.Add(dg1);
dg1.Dock = DockStyle.Fill;
dg1.Refresh();
dg1.DataSource = ds;
dg1.DataMember = sTable;
form2.Show();
if (conn != null)
{
conn.Close();
}
}
}
My results after search is fine when i comment that code:
(birthdate code) and i dont used as search of course.
//if (!String.IsNullOrEmpty(maskedTextBox1.Text))
// Query.Append(" AND birthdate like '" + maskedTextBox1.Text + "'");
But when i use the (birthdate code) i get us result only a blank row.
I think because the birthdate maskedTextbox have a mask: 00/00/0000
Any suggestion?
Thanks.
I think you should consider three things
1- You may replace OR with And in your query
I mean instead of using
da = new MySqlDataAdapter(
"SELECT * FROM data INNER JOIN country ON id_data = id_country
WHERE name like '" + textBox1.Text +
"'OR lastname like '" + textBox2.Text +
"'OR sex like '" + radiob +
"'OR birthdate like '" + maskedTextBox1.Text +
"'OR phone
_number like '" + maskedTextBox2.Text + "' ;", conn);
You may use
da = new MySqlDataAdapter(
"SELECT * FROM data INNER JOIN country ON id_data = id_country
WHERE name like '" + textBox1.Text +
"'AND lastname like '" + textBox2.Text +
"'AND sex like '" + radiob +
"'AND birthdate like '" + maskedTextBox1.Text +
"'AND phone_number like '" + maskedTextBox2.Text + "' ;", conn);
2- You have to build your query string based on your text boxes and else seeing if they have any value, something like this:
StringBuilder Query = "SELECT * FROM data INNER JOIN country ON id_data = id_country
WHERE 1=1 ";
if(!String.IsNullOrEmpty(textBox1.Text))
Query.Append(" AND name like '" + textBox1.Text);
....
3- Sql Injection vulnerabilities
oh my God !!! Some programming !!!
where clause must created by and/or ,... other clauses ,
so ,
two solutions exist :
On server Side by Store Procedure by below definition :
you must care by position of AND/OR in below :
CREATE PROCEDURE [dbo].[dbo_Bank_SELByFields]
(
#ID nvarchar(50) = NULL ,
#BankName nvarchar(50) = NULL ,
#BankCode nvarchar(50) = NULL ,
#Address nvarchar(50) = NULL ,
#BranchCode nvarchar(50) = NULL
)
AS
SELECT * FROM dbo.Bank WHERE
(
(#ID IS NULL OR ID = #ID) AND
(#BankName IS NULL OR BankName =#BankName) AND
(#BankCode IS NULL OR BankCode =#BankCode) AND
(#Address IS NULL OR Address =#Address) AND
(#BranchCode IS NULL OR BranchCode =#BranchCode)
) ORDER BY BankCode
//---you know call the Sp . OK?
and other solution in your business layer code :
if you use ORM such as Entity Framework , very easy By IQueryable object, you can use below :
var selectByEnyCondition=(from c in ctx.customer ...);
//---- you must add by below way :
if(!(String.IsNullOrEmpty(txtName.Text)))
{
selectByEnyCondition.Where(.....);
}
if(!String.IsNullOrEmpty(sex))
{
selectByEnyCondition= opportunites.Where(.....);
}
//------
/* **** beacuse you use by ADO.NET technique you should use StringBuilder -->*/
StringBuilder query;
query.add("SELECT * FROM BankTbl WHERE ");
if(!(String.IsNullOrEmpty(txtName.Text))){
query.Add("Name Like {0}",txtName.Text);
//-----now continue for build your criteria
king reguard
bye.....

Categories