I'm trying to create a login field using ASP.NET which will take input from the textbox fields and check them against the "user" table in my database. The columns are User ID and Password. But an error
System.Data.SqlClient.SqlException: 'Incorrect syntax near '`'
appears when the login form is used. I don't see any issue with the syntax...
I'm new to this so please excuse me if the error is obvious!
public partial class Login_Page : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
lblErrorMessage.Visible = false;
SqlConnection con = new SqlConnection("Data Source=JACKS-PC\\SQLEXPRESS;Initial Catalog=CBR;Integrated Security=True");
con.Open();
}
protected void btnLogin_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = "Data Source=JACKS-PC\\SQLEXPRESS;Initial Catalog=CBR;Integrated Security=True";
con.Open();
string userid = txtUsername.Text.Trim();
string password = txtPassword.Text.Trim();
SqlCommand cmd = new SqlCommand("select `user id`,`password` from user where `user id`='" + txtUsername.Text + "'and `password`='" + txtPassword.Text + "'", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
Session["username"] = txtUsername.Text.Trim();
Response.Redirect("Homepage.aspx");
}
else
{
lblErrorMessage.Visible = true;
}
con.Close();
}
}
Just remove the '`' characters to make it work.
Your code is vulnerable to injection try to add values with SqlCommand.Parameters.Add() method.
Use this code:
SqlCommand cmd = new SqlCommand("select userid, password from user where user id = #id and password = #password", con);
cmd.Parameters.Add("#id", SqlDbType.VarChar).Value = txtUsername.Text;
cmd.Parameters.Add("#password", SqlDbType.VarChar).Value = txtPassword.Text;
And as #marc_s mentioned, user id is not a valid column name, it should be like userid or if it has space in it is should be like: [user id]
there are many issues with your code :
Do not store plain text password in your program or app config.
Do not embed connection string into your program
` is not SQL Server Syntax.
never use string concatenation in your queries specifically if inputs are coming from users. Use Parameterized queries.
.
using (SqlCommand cmd = new SqlCommand("select 1 from tbl where id=#id", conn))
{
var idParameter = new SqlParameter()
idParameter.ParameterName = "#id";
idParameter.Value = 1234;
cmd.Parameters.Add(idParameter);
....
}
always dispose objects when you finish your work with them. For this use using(SqlConnection conn = new SqlConnection()).
all methods which implements IDisposable can be used within using statement
Related
Code :
private void button2_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
SqlConnection CON = new SqlConnection(#"Data Source(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\stud\Documents\ronak.mdf;Integrated Security=True;Connect Timeout=30");
SqlCommand cmd = new SqlCommand("Select * from Table where username= ' " + textBox1.Text + "' and password= ' " + textBox2.Text + "' ", CON);
SqlDataReader sda = cmd.ExecuteReader();
dt.Load(sda);
if (dt.Rows[0][0].ToString() == "1")
{
this.Hide();
login2 rk = new login2();
rk.Show();
}
else
{
MessageBox.Show("please chack you username and password");
}
}
This code is totally true but I have face some problem.
Your code has quite a number of different issues:
Your connection string is missing = after Data Source
You need to actually open the connection.
Do not use AttachDbFilename instead create and connect to a normal database.
Do not store plain-text passwords. Salt and hash them instead. Then compare the hash server-side, do not return it to the client.
You don't need a DataTable or DataAdapter, you can just use ExecuteScalar to retrieve a single value.
Dispose the connection and command with using.
Do not inject data into your queries. Use parameters instead.
const string query = #"
Select 1
from Table
where username= #username
and password= #password
";
using (var CON = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=ronak;Integrated Security=True;Connect Timeout=30"))
using (var cmd = new SqlCommand(query, CON))
{
cmd.Parameters.Add("#username", SqlDbType.NVarChar, 100).Value = textBox1.Text;
cmd.Parameters.Add("#password", SqlDbType.VarBinary, 256).Value = SaltAndHashPassword(textBox2.Text, textBox1.Text);
CON.Open();
var exists = cmd.ExecuteScalar() == 1;
CON.Close();
if (exists)
{
this.Hide();
login2 rk = new login2();
rk.Show();
}
else
{
MessageBox.Show("please chack you username and password");
}
}
First of all you forget = after Data source in sqlConnection
Second you are using bad names for variables
Third you dont need to use SqlCommand, you can replace it with SqlDataAdapter its more simple
Fourth you must use ( Using ) to dispose connection
Here`s the full code
private void button2_Click(object sender, EventArgs e)
{
DataTable table = new DataTable();
using (SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\stud\Documents\ronak.mdf;Integrated Security=True;Connection Timeout=30"))
{
connection.Open();
using (SqlDataAdapter adapter = new SqlDataAdapter($"Select * from Table where username= '{textBox1.Text}' and password= '{textBox2.Text}' ", connection))
{
adapter.Fill(table);
if (table.Rows.Count == 0)
{
MessageBox.Show("please chack you username and password");
return;
}
if (table.Rows[0][0].ToString() == "1")
{
this.Hide();
login2 rk = new login2();
rk.Show();
}
}
}
}
I am making a basic web form with basic fields like name, email, number.
I just want, when i enter the number, rest of the fields are populated in the other textboxes based on that number from sql server.
Any help would be appreciated.
Code is as follows :
string ConnectionString = ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSave_Click(object sender, EventArgs e)
{
string cmd = "IF NOT EXISTS(Select * from tbl_registration where Email = #Email OR MobileNo = #MobileNo) insert into tbl_registration values(#FirstName, #LastName,#Email,#MobileNo,#Address_1,#Address_2,#City,#State)";
using (SqlConnection con = new SqlConnection(ConnectionString))
{
using(SqlCommand com = new SqlCommand(cmd, con))
{
com.Parameters.AddWithValue("#FirstName", txtfname.Text.Trim());
com.Parameters.AddWithValue("#LastName", txtlname.Text);
com.Parameters.AddWithValue("#Email", txtemail.Text);
com.Parameters.AddWithValue("#MobileNo", txtmob_no.Text);
com.Parameters.AddWithValue("#Address_1", txtaddress1.Text);
com.Parameters.AddWithValue("#Address_2", txtaddress2.Text);
com.Parameters.AddWithValue("#City", txtcity.Text);
com.Parameters.AddWithValue("#State", txtstate.Text);
con.Open();
int success = com.ExecuteNonQuery();
if (success > 0)
{
Response.Write("<script>alert('Registration successfull')</script>");
}
else
{
Response.Write("<script>alert('Registration Not Sucessfull')</script>");
}
}
}
}
You should write the method definition as shown below on the text box changed event.
This is not the complete query answer. Here is a reference for you.
using (SqlConnection conn = new SqlConnection(CSs))
{
string query = "Your SQL Query here";
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds, "sometablename");
firstnametext.Text = Convert.ToString(ds.Tables["sometablename"].Rows[0]["Firstname"]);
}
Here you need to properly handle the null for the data table.
I'm coding a Windows Forms login page for an administration application. My problem is, that when I try to log on, I get the error message
System.InvalidOperationException: 'The connection is already open.'
Any help would be appreciated
public partial class Form1 : Form
{
MySqlConnection con = new MySqlConnection (#"Database= app2000; Data Source = localhost; User = root; Password =''");
int i;
public Form1()
{
InitializeComponent();
}
private void btnClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnLogin_Click(object sender, EventArgs e)
{
i = 0;
con.Open();
MySqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM adminlogin WHERE username='" + txtBoxUsername + "'AND password='" + txtBoxPassword + "'";
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
i = Convert.ToInt32(dt.Rows.Count.ToString());
if (i == 0)
{
lblerrorInput.Show();
}
else
{
this.Hide();
Main ss = new Main();
ss.Show();
}
}
}
Do not cache Connection, it's a typical antipattern, but recreate it when you need it
public partial class Form1 : Form {
...
//DONE: Extract method
private static bool UserExists(string userName, string password) {
//DONE: Do not cache connections, but recreate them
using (MySqlConnection con = new MySqlConnection (#"...") {
con.Open();
//DONE: wrap IDisposable into using
using (MySqlCommand cmd = con.CreateCommand()) {
cmd.CommandType = CommandType.Text;
//DONE: Make query being readable
//DONE: Make query being parametrized
cmd.CommandText =
#"SELECT *
FROM adminlogin
WHERE username = #UserName
AND password = #PassWord"; // <- A-A-A! Password as a plain text!
//TODO: the simplest, but not the best solution:
// better to create parameters explicitly
// cmd.Parameters.Add(...)
cmd.Parameters.AddWithValue("#UserName", txtBoxUsername);
cmd.Parameters.AddWithValue("#PassWord", txtBoxPassword);
// If we have at least one record, the user exists
using (var reader = cmd.ExecuteReader()) {
return (reader.Read());
}
}
}
}
Finally
private void btnLogin_Click(object sender, EventArgs e) {
if (!UserExists(txtBoxUsername.Text, txtBoxPassword.Text))
lblerrorInput.Show();
else {
Hide();
Main ss = new Main();
ss.Show();
}
}
You forgot to close the connection, use con.Close() at the end to close the connection and avoid this error the next time the event fires.
There are some mistakes in your code.
You should close the sql connection when you finished your process.
I suggest you to use using statement to dispose connection instance after complete database actions.
Also, you should use command parameters to prevent Sql injection.
You can declare connection string like this;
private string _connectionString = #"Database= app2000; Data Source = localhost; User = root; Password =''";
The method part looks like;
using (var con = new MySqlConnection(_connectionString))
{
i = 0;
con.Open();
MySqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM adminlogin WHERE username = #username and password = #password";
cmd.Parameters.AddWithValue("#username", txtBoxUsername);
cmd.Parameters.AddWithValue("#password", txtBoxPassword);
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
i = Convert.ToInt32(dt.Rows.Count.ToString());
if (i == 0)
{
lblerrorInput.Show();
}
else
{
this.Hide();
Main ss = new Main();
ss.Show();
}
con.Close();
}
First, don't cache your Connection objects. It's a terrible practice and I've had to go back and fix it every time I accept a new job and inherit code. Most database access classes implement IDisposable, so use using and take advantage of it to keep your code clean. FYI, Readers and Adapters are also IDisposable so you can do the same with them, too.
string command = "select stuff from mydata";
string connection = GetConnectionStringFromEncryptedConfigFile();
using (var conn = new SqlConnection(connection))
{
using (var cmd = new SqlCommand(command, conn))
{
cmd.Connection.Open();
//do stuff
}
}
Second, if you're forced to use a cached connection (i.e., you inherited horrible code and don't have time to fix it yet), check your State first.
if(conn.State != System.Data.ConnectionState.Open)
{
conn.Open();
}
Note that there are a lot more states than just Open and Closed, and if you try to open a connection that is busy, you'll still get errors. It's still a much wiser approach to use the IDisposable implementations with using so you don't have to worry about this sort of thing so much.
here is my viewprofile.aspx code where the binding will take place. im planning to bind my data in sql to my gridview but it is showing me all of the data(from sql) instead of that of the specific logged in customer. Here is my code:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["New"] != null)
{
bindgrid();
}
}
public void bindgrid()
{
SqlConnection conn = new SqlConnection("Data Source = 'PAULO'; Initial Catalog=ShoppingCartDB;Integrated Security =True");
SqlCommand cmd = new SqlCommand("select * from UserData WHERE Username = Username ", conn);
SqlDataAdapter da = new SqlDataAdapter("", conn);
da.SelectCommand = new SqlCommand("select * from UserData WHERE Username = Username", conn);
DataSet ds = new DataSet();
da.Fill(ds, "data");
GridView1.DataSource = ds.Tables[0].DefaultView;
GridView1.DataBind();
}
it is showing me all of the data(from sql) instead of that of the
specific logged in customer
That's because of the WHERE condition in your SELECT query which says WHERE Username = Username which is a TAUTOLOGY and will always be TRUE and so fetching all rows.
In essence your SELECT query is just doing
select * from UserData;
You need to specify the logged in customerid in WHERE condition to get his/her record.
Considering that you have a variable named Username in your ASP.NET code where you have stored current logged in customer name; then change your code like below
SqlCommand cmd = new SqlCommand("select * from UserData WHERE Username = #Username ", conn);
cmd.Parameters.AddWithValue("#Username", Username);
da.SelectCommand = cmd;
I have a table name is 'User_tbl' where i am saving data of all registered users and the same table is being used to verify the users during Login.
I want to update only 'LastSeen' column with current datetime after login.
Look at this picture.
code behind
protected void Submit(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("select * from User_tbl where UserName =#username and Password=#password", con);
cmd.Parameters.AddWithValue("#username", txtUserName.Text);
cmd.Parameters.AddWithValue("#password", txtPWD.Text);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
//to define the user seesion (starting user session)
Session["username"] = txtUserName.Text;
Response.Redirect("default2.aspx");
}
else
{
ClientScript.RegisterStartupScript(Page.GetType(), "LoginValidate", "<script language='javascript'> document.getElementById('errorMessage').innerHTML = 'Invalid Username or Password'</script>");
}
}
Do you mean something like this?
SqlConnection sqlConn = new SqlConnection(connection string here);
SqlCommand sqlComm = new SqlCommand();
sqlComm = sqlConn.CreateCommand();
sqlComm.CommandText = #"UPDATE User_tbl SET LastSeen=GetDate() WHERE UserName='#userName'";
sqlComm.Parameters.Add("#userName", SqlDbType.VarChar);
sqlComm.Parameters["#userName"].Value = txtUserName.Text;
sqlConn.Open();
sqlComm.ExecuteNonQuery();
sqlConn.Close();
You'd need to place something along those lines in your 'if (dt.Rows.Count > 0)' code.
You may wish to reuse the same connection that you created for your SELECT statement.
Many other options are available. Often this sort of thing is best achieved using a stored procedure, where you can check the login credentials and perform any related updates in a single request to the database server.