using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
namespace todoassignment1
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Visible = false;
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
string valueUser = txtUsername.Text;
SqlConnection db = new SqlConnection(SqlDataSource1.ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
//User is the name of the table, UserName is the column
cmd.CommandText = "INSERT User (UserName) VALUES ('" + valueUser + "')";
cmd.Connection = db;
db.Open();
try
{
cmd.Connection.Open();
cmd.ExecuteNonQuery();
Label1.Text = "Success writing into database!";
Label1.Visible = true;
}
catch (Exception ex)
{
Label1.Text = "Error writing into database.";
Console.WriteLine(ex.Message);
Label1.Visible = true;
}
finally
{
db.Close();
}
}
}
}
I added the SqlDataSource1 on the Default.aspx page, which seems to be done successfully as I can see the column names of the User table in the gridview. The table is empty, and all I'm trying to do is take input in a textbox and send it to the UserName column.
I'm not very good at debugging, but I have noticed a few errors which I have spent hours researching.
Things I've tried:
SQL SMS > tools > options > designers > CHECK prevent saving changes that require table re-creation
Added using System.Data;
Added cmd.Connection.Open();
Added an exception to be caught in the catch statement
Recreate entire database
Quadruple checked things like txtUsername being the correct textbox ID
Reconfigure SqlDataSource1 over and over, delete and recreate
Confirm that the connectionString in web.config is correct
Create the new SQLConnection with the exact string in web.config
SqlConnection db = new SqlConnection("Data Source=NAME-PC\\SQLEXPRESS;Initial Catalog=Assignment;Integrated Security=True");
Changed the insert line from concatenation to just "INSERT User (UserName) VALUES ('asdf')" to simplify code, still doesn't work.
Tried other syntax
cmd.CommandText = "INSERT INTO User (UserName) VALUES (#username)";
cmd.Parameters.Add("#username", SqlDbType.NVarChar, 50);
cmd.Parameters["#username"].Value = txtUsername.Text.ToString();
Clues from the debugger:
saw several "System.InvalidCastExceptions when digging through cmd in autos
errorCS0103: the name 'ExecuteNonQuery' does not exist in the current context
Always see System.InvalidOperationException after running
Please help.
static void BtnSubmit_Click(object sender, EventArgs e)
{
string valueUser = "test"; //txtUsername.Text;
using (SqlConnection db = new SqlConnection("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=test;Integrated Security=True"))//SqlDataSource1.ConnectionString);
{
SqlCommand cmd = new SqlCommand("INSERT INTO dbo.[User] (UserName) VALUES (#valueUser)", db);
cmd.Parameters.Add("#valueUser", SqlDbType.VarChar, 50).Value = valueUser;
//cmd.CommandType = CommandType.Text;
//User is the name of the table, UserName is the column
//cmd.CommandText = "INSERT User (UserName) VALUES (#valueUser)";
//cmd.Connection = db;
db.Open();
try
{
//cmd.Connection.Open();
cmd.ExecuteNonQuery();
/*Label1.Text =*/
Console.WriteLine("Success writing into database!");
//Label1.Visible = true;
}
catch (Exception ex)
{
/*Label1.Text =*/
Console.WriteLine("Error writing into database.");
Console.WriteLine(ex.Message);
//Label1.Visible = true;
}
//finally
//{
//db.Close();
//}
}
}
A couple of issues.
The syntax for insert is INSERT INTO TABLE (COLUMNS) VALUES (VALUES) You had "INSERT User (UserName)"...
USER is a reserved word in SQL. If you insist upon using it as your table name it must be wrapped in square brackets.
You were opening the connection twice. Not really a problem per se, but unnecessary.
Always, always, always be using parameters.
I simplified things a little.
If you modify the method I've attached you should be able to copy paste it.
Related
I am creating a basic registration page using ASP.NET websites and C# and am trying to link the logins to a database I have created in Visual Studio 2017 and am constantly getting the error -
'System.NullReferenceException: 'Object reference not set to an instance of an object.'
System.Data.Common.DbCommand.ExecuteScalar(...) returned null.
and cannot understand why, code below any help appreciated.
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
public partial class Registration : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ValidationSettings.UnobtrusiveValidationMode = UnobtrusiveValidationMode.None;
if (IsPostBack)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
string checkuser = "SELECT * FROM [Table] WHERE UserName='" + TextBoxUN.Text + "'";
SqlCommand com = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
if (temp == 1)
{
Response.Write("User already exists, please enter a different username");
}
conn.Close();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
string insertQuery = "INSERT INTO Table (UserName,Email,Password,Country) values(#Uname ,#email , #password ,#country)";
SqlCommand com = new SqlCommand(insertQuery, conn);
com.Parameters.AddWithValue("#Uname" , TextBoxUN.Text);
com.Parameters.AddWithValue("#email" , TextBoxEmail.Text);
com.Parameters.AddWithValue("#password" , TextBoxPass.Text);
com.Parameters.AddWithValue("#country" , DropDownListCountry.SelectedItem.ToString());
com.ExecuteNonQuery();
Response.Redirect("Manager.aspx");
Response.Write("Registration Successful");
conn.Close();
}
catch (Exception ex)
{
Response.Write("Error:" + ex.ToString());
}
}
}```
If you want to check if user exists, there's no need in ExecuteScalar() with value:
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
when user doesn't exist, com.ExecuteScalar() returns null and you have a problem.
Code
private static bool UserExists(string userName) {
if (null == userName)
return false;
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString)) {
conn.Open();
//DONE: parametrized query
//DONE: 1 instead of * - we don't want all columns to be returned
string sql =
#"select 1
from [Table]
where UserName = #userName";
using (SqlCommand com = new SqlCommand(sql, conn)) {
com.Parameters.Add("userName", SqlDbType.VarChar).Value = userName;
// user exists if cursor is not empty (we have at least one record)
return com.ExecuteScalar() != null;
}
}
}
protected void Page_Load(object sender, EventArgs e) {
ValidationSettings.UnobtrusiveValidationMode = UnobtrusiveValidationMode.None;
if (IsPostBack && UserExists(TextBoxUN.Text))
Response.Write("User already exists, please enter a different username");
}
I have connected my SQL database to my aspx.net form but when I entered the details in the form, it does not seem to update in my SQL Table. I've checked the codes and there doesn't seem to be any errors. Could anyone see what's wrong with my code?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data.Sql;
public partial class CustomerLogin : System.Web.UI.Page {
public string sqlTest = "Data Source=TEAFAMILY;Initial Catalog=Bolsen;Integrated Security=True";
protected void Page_Load(object sender, EventArgs e) {
}
static readonly string scriptSuccessNewAccount =
"<script language=\"javascript\">\n" +
"alert (\"Your account has been succesfully created - Thank You!\");\n" +
"</script>";
protected void Button1_Click1(object sender, EventArgs e) {
SqlConnection mDB = new SqlConnection(sqlTest);
mDB.Open();
Type csType = this.GetType();
SqlCommand cmd;
SqlDataReader rdr;
string strSQLSelect = "SELECT cEmail FROM Customers ORDER BY cEmail";
cmd = new SqlCommand(strSQLSelect, mDB);
Console.Write(cmd);
rdr = cmd.ExecuteReader();
//insert new record
string strSQLInsert = "INSERT INTO"
+ " Customers (cFirstname, cLastname, cNumber, cCompanyname, cAdd, cEmail, cPassword)"
+ " VALUES (#FN, #LN, #Num, #Cname, #Add, #Email, #Pw)";
cmd = new SqlCommand(strSQLInsert, mDB);
cmd.Parameters.AddWithValue("#FN", txtFN.Text);
cmd.Parameters.AddWithValue("#LN", txtLN.Text);
cmd.Parameters.AddWithValue("#Num", txtPN.Text);
cmd.Parameters.AddWithValue("#Cname", txtComp.Text);
cmd.Parameters.AddWithValue("#Add", txtCompAdd.Text);
cmd.Parameters.AddWithValue("#Email", txtEmail.Text);
cmd.Parameters.AddWithValue("#Pw", txtPW.Text);
cmd.ExecuteNonQuery();
mDB.Close();
ClientScript.RegisterStartupScript(csType, "Success", scriptSuccessNewAccount);
}
}
You are not closing your SqlDataReader. Asides from not calling rdr.Read() and getting any values, you need to call rdr.Close() before executing your second sql statement.
Per MSDN - While the SqlDataReader is being used, the associated SqlConnection is busy serving the SqlDataReader, and no other operations can be performed on the SqlConnection other than closing it. This is the case until the Close method of the SqlDataReader is called. For example, you cannot retrieve output parameters until after you call Close.
I have just started working on c#.net. below is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
public partial class Default2 : System.Web.UI.Page
{
//SqlConnection con = new SqlConnection("Data Source=ADMIN-PC\\SQLEXPRESS;Initial Catalog=register;Integrated Security=True");
protected void Page_Load(object sender, EventArgs e)
{
}
private const string strconneciton = "Data Source=ADMIN-PC\\SQLEXPRESS;Initial Catalog=register;Integrated Security=True";
SqlConnection con = new SqlConnection(strconneciton);
protected void Button1_Click(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = new SqlCommand("insert into user(uname, address,
email, number) values('" + TextBox1.Text + "', '" + TextBox2.Text + "', '" +
TextBox3.Text + "', '" +TextBox4.Text+ "')", con);
cmd.ExecuteNonQuery();
con.Close();
}
}
and I am getting this error
An exception of type 'System.Data.SqlClient.SqlException' occured in 'System.Data.dll but was not handled in user code
please help. I am using microsoft sql server management studio.
Do not hardcode sql queries:
They are difficult to read (so you can easily commit syntax error: in your case number is MS Sql's reserved word and should be put as [number])
They are prone to errors (e.g. what if TextBox2.Text contains an apostroph, ')
They are vulnerable to Sql Injection
I suggest extracting a method:
private void CoreInsert() {
//Done: wrap IDisposable into using, do not close explicitly
//TODO: do not hardcode strConnection, but read from settings
using (SqlConnection con = new SqlConnection(strConnection)) {
con.Open();
// Make sql
// 1. Readable: can you see a problem with "Number" now?
// 2. Parametrized
string sql =
#"insert into [user](
uname,
address,
email,
[number]) -- <- number is MS SQL's reserved word, put it as [number]
values(
#prm_uname,
#prm_address,
#prm_email,
#prm_number)";
//Done: wrap IDisposable into using
using (SqlCommand cmd = new SqlCommand(sql, con)) {
cmd.Parameters.AddWithValue("#prm_uname", TextBox1.Text);
cmd.Parameters.AddWithValue("#prm_address", TextBox2.Text);
cmd.Parameters.AddWithValue("#prm_email", TextBox3.Text);
//TODO: check actual field's type here
cmd.Parameters.AddWithValue("#prm_number", TextBox4.Text);
cmd.ExecuteNonQuery();
}
}
}
Then call the method
protected void Button1_Click(object sender, EventArgs e) {
CoreInsert();
}
Use Parameters function to add values to your command strings, always. I think it's problem about you are sending value "number" as char and you may define it as int at your database. So you can try to delete single qutoes from Textbox4.Text.
But if you want to make it better, use parameters. Like that.
SqlCommand cmd = new SqlCommand("insert into user(uname, address,
email, number) values(#uname,#address,#email,#number)", con);
cmd.Parameters.AddWithValue("#uname", TextBox1.Text);
cmd.Parameters.AddWithValue("#address", TextBox2.Text);
cmd.Parameters.AddWithValue("#email", TextBox3.Text);
cmd.Parameters.AddWithValue("#number", TextBox4.Text);
cmd.ExecuteNonQuery();
This will also prevent any SQL Injection problems.
I am creating a simple Hospital Management System, and I was having a problem connecting to the database.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.Sql;
using System.Data.SqlClient;
public partial class Login : System.Web.UI.Page
{
SqlConnection connectionstring = new SqlConnection("Server=.\\SQLEXPRESS;Database=TestDB;User Id=test; Password = woooow; ");
protected void Button1_Click1(object sender, EventArgs e)
{
string cmdText = "SELECT 1 FROM Login WHERE Username = '" + TextBox1.ToString() + "' AND Password = '" + TextBox2.toString()+ "'";
// using (SqlConnection cnn = new SqlConnection("Server=.\\SQLEXPRESS;Database=TestDB"))
using (SqlCommand SelectCommand = new SqlCommand(cmdText, connectionstring))
{
SqlDataReader myReader;
connectionstring.Open();
myReader = SelectCommand.ExecuteReader();
int count = 0;
while (myReader.Read())
{
count = count + 1;
}
if (count == 1)
{
//open form
}
else
{
}
}
}
}
this is the code I use for the Login form in a normal C# application. but looks like I am doing something wrong in TextBox1.toString() and TextBox2.toString().
How can I take the exact value of the textbox? by googling around, I saw many posts which say it, but everything is different from each other and making me really confused about it.
So, which is the best way to do that?
Thanks.
TextBox1.ToString() returns the fully qualified name of the class textbox that is
System.Windows.Forms.TextBox, Text:
The exact property that returns the content of a TextBox is the Text property, however, simply replacing your TextBox1.ToString() with TextBox1.Text, while working, could be the cause of other potential and more dangerous errors.
SqlCommand should use the parameters collection, not build the sql text concatenating strings. This is well known as a source of errors (parsing decimals, dates and strings with embedded quotes) and a big security risk called Sql Injection.
Instead your code with parameters is
public partial class Login : System.Web.UI.Page
{
private string conString = "Server=.\\SQLEXPRESS;Database=TestDB;User Id=test; Password = woooow; ";
protected void Button1_Click1(object sender, EventArgs e)
{
int count = 0;
string cmdText = #"SELECT 1 FROM Login
WHERE Username = #uname
AND Password = #pwd";
using (SqlConnection cnn = new SqlConnection(conString))
using (SqlCommand cmd = new SqlCommand(cmdText, cnn))
{
cnn.Open();
cmd.Parameters.Add("#uname", SqlDbType.NVarChar).Value = textBox1.Text;
cmd.Parameters.Add("#pwd", SqlDbType.NVarChar).Value = textBox1.Text;
using(SqlDataReader myReader = SelectCommand.ExecuteReader())
{
while (myReader.Read())
count = count + 1;
}
}
if (count == 1)
{
//open form
}
else
{
}
}
}
Notice that I have also made your connection string global and created a local SqlConnection object. To be sure to dispose the object the best approach is having everything local and put the disposable object inside a using statement.
Consider also that storing password in clear text is another security risk. This question explain The Best way to store passwords in a database
when I developing just registration page this error occurred
error:An exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll but was not handled in user code
code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
public partial class Registration : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
String checkuser = "select count(*) from [UserData] where User Name='"+ TextBox1UN.Text +"'";
SqlCommand comm = new SqlCommand(checkuser,conn);
int temp = Convert.ToInt32(comm.ExecuteScalar().ToString());
if(temp==1)
{
Response.Write("user allready exists");
}
conn.Close();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
String InserQuery = "insert into [UserData](UserName,Email,Password,Country)values(#Uname,#email,#pass,#country)";
SqlCommand comm = new SqlCommand(InserQuery, conn);
comm.Parameters.AddWithValue("#Uname", TextBox1UN.Text);
comm.Parameters.AddWithValue("#email", TextBox2EI);
comm.Parameters.AddWithValue("#pass", TextBox3PW);
comm.Parameters.AddWithValue("#country", DropDownList1cont.SelectedItem.ToString());
comm.ExecuteNonQuery();
Response.Write("Registration is succesful");
Response.Write("Administrator.aspx");
conn.Close();
}
catch (SqlException ex)
{
Response.Write("Error:"+ex.ToString());
}
}
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
}
}
aspx file:
<asp:SqlDataSource ID="SqlDataSourceRegistration"
runat="server"
ConnectionString="<%$ConnectionStrings:RegistrationConnectionString %>"
OnSelecting="SqlDataSourceRegistration_Selecting"
SelectCommand="SELECT * FROM [UserData]" >
</asp:SqlDataSource>
Your Query is not valid there is space between User Name and User is a keyword in sql. Your query should look like this
"select count(*) from [UserData] where UserName=#username";
Use Parameterized SQL
Add parameters to the command instead of concatenating values
comm.Parameters.AddWithValue("#username",TextBox1UN.Text);
A tip: Your code is very hackable / unsecure... because you put user input into the sql string you should use parameters instead.
You also have a space in your field name 'User Name' which I'm guessing is your issue so I put it as 'UserName'.
You should also put your code into a try catch statement so you can read the error.
try
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
using (SqlCommand command = new SqlCommand(
"SELECT COUNT(*) from [UserData] where UserName= #Name", connection))
{
// Add new SqlParameter to the command.
command.Parameters.Add("#Name", SqlDbType.NVarChar).Value = TextBox1UN.Text;
int temp = Convert.ToInt32(command.ExecuteScalar().ToString());
if(temp==1)
{
Response.Write("user allready exists");
}
}
}
catch (Exception ex)
{
// Display the exception's data dictionary.
foreach (DictionaryEntry pair in ex.Data)
{
Console.WriteLine("{0} = {1}", pair.Key, pair.Value);
}
}