I'm building a user registration page that save user's info into a local database. However I get a SqlException error. Does anyone know what I'm doing wrong here? I'm developing the program in ASP.net and using the local database server.
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegisterConnectionString"].ConnectionString);
conn.Open();
string checkUser = "select count(*) from Table where userName = '" + txtUN.Text + "'";
SqlCommand comm = new SqlCommand(checkUser, conn);
int temp = Convert.ToInt32(comm.ExecuteScalar().ToString());
if (temp == 1)
{
Response.Write("user already exist");
}
conn.Close();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegisterConnectionString"].ConnectionString);
conn.Open();
string insertQuery = "insert into Table(UserName, name, Address, e-Mail, IC, phone, password) values(#Uname, #name, #add, #mail, #ic, #phone, #pswrd) ";
SqlCommand comm = new SqlCommand(insertQuery, conn);
comm.Parameters.AddWithValue("#Uname", txtUN.Text);
comm.Parameters.AddWithValue("#name", txtName.Text);
comm.Parameters.AddWithValue("#add", txtAdd.Text);
comm.Parameters.AddWithValue("#mail", txtEmail.Text);
comm.Parameters.AddWithValue("#ic", txtIC.Text);
comm.Parameters.AddWithValue("#phone", txtPhone.Text);
comm.Parameters.AddWithValue("#pswrd", txtPsswrd.Text);
comm.ExecuteNonQuery();
Response.Redirect("Default.aspx");
Response.Write("registration was succesful");
conn.Close();
}
catch(Exception ex)
{
Response.Write("error"+ex.ToString());
}
}
You don't give the details of the exception, (ie: exception.Message and exception.InnerException.Message) but from your code I think you have the classical "Syntax Error Near ...."
This is caused by the presence of a reserved keyword in your query text. This reserved keyword is TABLE. You could fix it enclosing the word in square brackets (or better change the name of the table to somenthing more meaningful)
string checkUser = "select count(*) from [Table] where userName = ...";
A part from this, remember to use always parameterized queries also for simple tasks as looking for logins. Last but not least, storing password in clear text inside the database is a big NO-NO from a security standpoint. Everyone, having access to your database using some kind of administrative tool, could look at the passwords of your users, someone could intercept the network traffic between user pc and database server and see the credentials sent by your application. So, please, search for password hashing on this site to find a more secure approach to this problem
Related
I have written this simple code in c# VS 2010 to store the name and login to my local table. When i run it is shows me this massage:
"incorrect syntax near the nvarchar"
using System;
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string name =textBox1.Text;
string login =textBox2 .Text;
string sqlquery;
SqlConnection cn = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename= C:\\Users\\Safeen\\Documents\\Visual Studio 2010\\Projects\\WindowsFormsApplication12\\WindowsFormsApplication12\\Database1.mdf;Integrated Security=True;User Instance=True");
cn.Open();
sqlquery = "INSERT INTO Table1 (user, password) VALUES ('" + name + "','" + login + "')";
try
{
SqlCommand command = new SqlCommand(sqlquery, cn);
command.Parameters.AddWithValue("#user ", textBox1.Text);
command.Parameters.AddWithValue("#password ", textBox2.Text);
command.ExecuteNonQuery();
MessageBox.Show("Table1 Added");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
textBox1.Clear();
textBox2.Clear();
cn.Close();
}
}
You're providing multiple values for your parameters.
You're saying the db value of user = name and password = login, then ALSO passing in two parameters called #user and #password, without telling SQL which set is correct.
You definitely want to go with SqlCommand option and also set the SqlCommand.CommandType to the correct value. Assigning parameters like this is safe; dropping variables directly into the VALUES() clause (like you had in your original post) can open yourself to SQL Injection attacks.
I edited out a recommendation to use Stored Procs here. That's more of a personal preference I have, as per the little discussion in the comments; I like to separate out my database layer. Also, it means that if anything ever changes you just have to update your Stored Proc once instead of finding your query everywhere it could be in your app.
I'm trying to create a Registration Page using Webforms that'll connect to a MySQL databse and insert the data, but it throws up an ArgumentException (even though I believe I'm following my tutorial exactly) and will not insert the data into the table.
My C# code for the Registration page is thus:
public partial class Registration : System.Web.UI.Page
{
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
String queryStr;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void registerEventMethod(object sender, EventArgs e)
{
registerUser();
}
private void registerUser()
{
String connString =
System.Configuration.ConfigurationManager.ConnectionStrings["WebAppConnString"].ToString();
conn = new MySql.Data.MySqlClient.MySqlConnection(connString);
conn.Open();
queryStr = "";
queryStr = "INSERT INTO seniorschema.registration (Password1, Email, FirstName, LastName, Password2, Code)" +
"VALUES('" + PasswordTextBox1.Text +"','"+ EmailTextbox.Text +"','"+ firstNameTextBox.Text+"','"+ LastNameTextBox.Text + "' ,'"+ PasswordTextBox2.Text +"', '"+ CodeTextBox.Text + "' )";
cmd = new MySql.Data.MySqlClient.MySqlCommand(queryStr, conn);
cmd.ExecuteReader();
conn.Close();
}
}
And my connection in the WebConfig file is here:
<connectionStrings>
<add name="WebAppConnString"
connectionString="server=localhost;ID=webuser;pwd=password;database=seniorschema;"
providerName="MySql.Data.MySqlClient"/>
</connectionStrings>
Any Help would be most appreciated. Thanks!
I don't know what tutorial you are reading but they should never teach to use string concatenation when building an sql command text.
However, the error you get is from the connectionstring.
You should write
String connString =ConfigurationManager.ConnectionStrings["WebAppConnString"].ConnectionString;
There is also an error in the definition of the connectionstring in the web.config ( a typo?)
It is Uid=.... not ID=....
And here how I would write the code that add the record.
using MySql.Data.MySqlClient;
....
queryStr = #"INSERT INTO seniorschema.registration
(Password1, Email, FirstName, LastName, Password2, Code)
VALUES(#pwd, #email, #first, #last, #pwd2, #code";
using(MySqlConnection conn = new MySqlConnection(connString))
using(MySqlCommand cmd = new MySqlCommand(queryStr, conn))
{
conn.Open();
cmd.Parameters.AddWithValue("#pwd",PasswordTextBox1.Text);
cmd.Parameters.AddWithValue("#email",EmailTextbox.Text );
cmd.Parameters.AddWithValue("#first",firstNameTextBox.Text);
cmd.Parameters.AddWithValue("#last",LastNameTextBox.Text );
cmd.Parameters.AddWithValue("#pwd2",PasswordTextBox2.Text );
cmd.Parameters.AddWithValue("#code",CodeTextBox.Text);
int rowAdded = cmd.ExecuteNonQuery();
}
This approach remove the string concatenation with all the complexities required to correctly code the quotes around the values, also removes any possibility of Sql Injection
Finally, but this is really an argument too broad and not immediately linked to your question.
It is a bad practice, from a security standpoint, to store passwords in clear text. If someone could get a copy of or read the registration table, he/she will be able to read the passwords of all users registered. There are proven methods that store an hash of the password to make them unreadable to onlookers
After setting up my SqlDataSource on another page to display the values, they come up as 2 blanks for the 2 times I entered test values on the comments page.
I think I'm missing something in getting them into the table in the SQL Server database value?
I'm not sure what information is needed here, so please inform me.
Thanks in advance
EDIT #1 for user request for CODE
protected void btnSend_Click(object sender, EventArgs e)
{
Page.Validate("vld2");
SendMail();
lblMsgSend.Visible = true;
//SQL Server Database
SqlConnection conn; //manages connection to database
SqlCommand cmd; //manages the SQL statements
string strInsert; //SQL INSERT Statement
try
{
//create a connection object
conn = new SqlConnection("Data Source=localhost\\sqlexpress;" +
"Initial Catalog=RionServer;" +
"Integrated Security=True;");
//Build the SQL INSERT Document
strInsert = "INSERT INTO CommentsAdmin (Name,Phone,Email,Comments)"
+ "VALUES(#Name,#Phone,#Email,#Comments);";
//associate the INSERT statement with the connection
cmd = new SqlCommand(strInsert, conn);
//TELL the SqlCommand WHERE to get the data from
cmd.Parameters.AddWithValue("Name", txtName.Text);
cmd.Parameters.AddWithValue("Phone", txtPhone.Text);
cmd.Parameters.AddWithValue("Email", txtEmail.Text);
cmd.Parameters.AddWithValue("Comments", txtComment.Text);
//open the connection
cmd.Connection.Open();
//run the SQL statement
cmd.ExecuteNonQuery();
//close connection
cmd.Connection.Close();
//display status message on the webpage
lblMsgSend.Text = "Thank you for the comment! Please hit the 'Return to Main Page' to return to the Main Page!";
}
catch (Exception ex)
{
lblMsgSend.Text = ex.Message;
}
txtPhone.Text = "";
txtEmail.Text = "";
txtName.Text = "";
txtComment.Text = "";
}
EDIT #2
The values seems to be empty for the Name, Phone, Email, and Comments in the database and when I test the query, so I think it's registering the entries, just not taking the values into the SQL?
EDIT #3
Due to a suggestion by coder and rs, I've done what they've said. And now I get this error.
"String or binary data would be truncated. The statement has been terminated."
The code has been updated as well.
EDIT #4
This question is a follow up for SQL Server Error, 'Keyword not supported 'datasource'.
Remove all the "" similar to this txtPhone.Text = ""; before entering values to SQL as Server you're entering null values to that. So even if you give some values to the textbox it takes predefined NULL values and it dosen't enter either of them.
This is my first time asking a question on StackOverflow, so I apologize in advance if I ask someone improper. I couldn't find anything to help me while researching this for the past few days, so thank you in advance to anyone who tries to help.
I am making a database that allows people to register and log-in. I am using C# in VS2012.
Below is my log-in code and I am running into some trouble when testing. It iterates through everyone in the database and tells me that log-in has failed till it gets to the right user.
private void button1_Click_1(object sender, EventArgs e)
{
try
{
cn.Open();
}
catch (Exception)
{
MessageBox.Show("Did not connect");
}
SqlCommand cmd = new SqlCommand("SELECT * FROM [Users]", cn);
cmd.Connection = cn;
SqlDataReader reader = null;
reader = cmd.ExecuteReader();
while (reader.Read())
{
if (textBox1.Text == (reader["Username"].ToString()) && textBox2.Text == (reader["Password"].ToString()))
{
MessageBox.Show("Logged in");
}
else
{
MessageBox.Show("Login has failed. Please check your Username and Password.");
}
}
cn.Close();
}
As for my registration portion, I'm not sure if it is a VS2012 thing or what, but the information doesn't get saved into the database after I end debug and then go back to debug again.
private void button1_Click_1(object sender, EventArgs e)
{
cn.Open();
SqlCommand cm1 = new SqlCommand("INSERT INTO Users (Username, Password) VALUES (#Username, #Password)", cn);
SqlCommand cm2 = new SqlCommand("INSERT INTO Contact(Name, Address, City, State, PostalCode, Email, PhoneNumber) VALUES(#Name, #Address, #City, #State, #PostalCode, #Email, #PhoneNumber)", cn);
cm1.Parameters.AddWithValue("#Username", textBox1.Text);
cm1.Parameters.AddWithValue("#Password", textBox2.Text);
cm2.Parameters.AddWithValue("#Name", textBox3);
cm2.Parameters.AddWithValue("#Address", textBox4);
cm2.Parameters.AddWithValue("#City", textBox5);
cm2.Parameters.AddWithValue("#State", textBox6);
cm2.Parameters.AddWithValue("#PostalCode", textBox7);
cm2.Parameters.AddWithValue("#Email", textBox8);
cm2.Parameters.AddWithValue("#PhoneNumber", textBox9);
try
{
int affectedRows = cm1.ExecuteNonQuery(); //+cm2.ExecuteNonQuery();
if (affectedRows > 0)
{
MessageBox.Show("Insert Sucsess!", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Insert Failed!", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
cn.Close();
}
When you have a database file in you project and you build the project, the database file could be copied from the root project folder into the output (bin\debug or bin\release) folder.
This behavior is controlled by the Copy To Output Directory property of the database file.
If you have this property set to Copy Always then, every time you build your project a fresh copy of the database file is copied from the root project folder to the output directory overwriting the one already there and destroying the changes you have made in the previous debug session.
A suggested fix is to change this property to Copy Never or Copy if Newer
See a detailed explanation on MSDN at this page
For the first part of your question you could avoid to loop on every user adding a WHERE clause to your sql text. Just be aware that you should never use string concatenation to build your sql strings, instead you use ALWAYS the parameters. (Why? You avoid Sql Injection and text single quote parsing/doubling)
string sqlText = "SELECT * FROM [Users] WHERE Username = #usr AND [Password] = #psw";
SqlCommand cmd = new SqlCommand(sqlText, cn);
cmd.Parameters.AddWithValue("#usr", textbox1.Text);
cmd.Parameters.AddWithValue("#psw", textbox2.Text);
SqlDataReader reader = cmd.ExecuteReader();
if(reader.HasRows)
// You have found the user....
Another bit of advice. Do not store the passwords in clear text inside your database. Store always an hash of this string and, on search, compute the hash value and search for it instead of a clear password.
In order for you to get this working you will need a WHERE clause in your SELECT. However, I would not recommend to use
SqlCommand cmd = new SqlCommand("SELECT * FROM [Users] WHERE Username='" + textBox1.Text + "'", cn);
because of possible SQL injection.
Please learn how to use Stored Procedures and how to Execute them from your C# code.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
Hi I'm trying to get data from a local sql service database to take the input from a user register form. but when i push the button its not recorded onto the serviceable database.
do i need to use execute non query? how would i fix this code up? thanks
using System.Data.Sql;
using System.Data.SqlClient;
namespace Paddle_Power
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show();
string connection = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\PaddlePower.mdf;Integrated Security=True;User Instance=True";
SqlConnection cn = new SqlConnection(connection);
try
{
cn.Open();
MessageBox.Show("open");
}
catch (Exception)
{
MessageBox.Show("Did not connect");
}
string username = textBox1.Text;
string password = textBox2.Text;
string sqlquery = ("SELECT * FROM User WHERE Username = '" + textBox1.Text + "'");
sqlquery = "INSERT INTO [User] (Username, Password) VALUES ('" + textBox1.Text + "','" + textBox2.Text + "')";
SqlCommand command = new SqlCommand(sqlquery, cn);
command.Parameters.AddWithValue("Username", username);
command.Parameters.AddWithValue("Password", password);
command.Parameters.Clear();
}
}
}
Something along the lines of the following should hopefully do it. There's some room for improvement, but I at least hope it solves the problem you're having.
string connection = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\PaddlePower.mdf;Integrated Security=True;User Instance=True";
object queryResult = null;
using (SqlConnection cn = new SqlConnection(connection))
{
cn.Open(); // Open connection
// SELECT
using (SqlCommand cmd = new SqlCommand("SELECT * FROM User WHERE Username = #Username AND Password = #Password", cn))
{
cmd.Parameters.AddWithValue("#Username", textBox1.Text);
cmd.Parameters.AddWithValue("#Password", textBox2.Text);
queryResult = cmd.ExecuteScalar();
}
// INSERT
using (SqlCommand cmd = new SqlCommand("INSERT INTO [User] (Username, Password) VALUES (#Username, #Password)", cn))
{
cmd.Parameters.AddWithValue("#Username", textBox1.Text);
cmd.Parameters.AddWithValue("#Password", textBox2.Text);
cmd.ExecuteNonQuery(); // or int affected = cmd.ExecuteNonQuery()
}
}
You can requse the first SqlCommand object or create a new one. There's very little difference with either way you choose to do it.
queryResult is just there for storing the result of cmd.ExecuteScalar(). You can map it to an object if you want (when selecting multiple columns) or cast it to a new type (if you're selecting a single column).
The direct answer is yes, you need to execute a non query. You see, you've prepared the command but you have not issued it. jstnasn's example should be very helpful. Take note of the using statements -- these will implicitly close the command when you exit the using statement, thus ensuring that the command is always closed when done.
The same occurs for the SqlConnection -- the using helps make sure that the connection is disposed of properly. However, if your database connection string allows connection pooling, then I believe the using statement will merely kill your object, without actually killing the connection to the database. This is advantageous because you will have lower I/O overhead the next time you need to open a database connection -- you'll just be connecting to an existing TCP/IP socket rather than opening a new on.
You have no parameters, nor do you ever actually send the query to the database
// parameter placeholders defined with #parameter_name
sqlquery = "INSERT INTO [User] (Username, Password) VALUES (#username, #Password);
SqlCommand command = new SqlCommand(sqlquery, cn);
command.Parameters.AddWithValue("#Username", username);
command.Parameters.AddWithValue("#Password", password);
// This will make the query happen on the database.
// It will handle sending the parameters and all that good stuff
// http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx
command.ExecuteNonQuery();