validation of data with sql and c# - c#

i've been struggling to understand how to validate data i entered in an input in an .aspx webform,
say username and password, i've tried many things, tried reading about it and looking for solutions but all of them are really messy with a lot of things i don't really need.
It is for a school project in my school and i already set up a working database, and i already made a register page, that works and it submits it to the database.
Our teachers supplied us with a DalAccess file, that is stored in the App_Data folder in my project.
This is the code inside of it:
public class DalAccess
{
private OleDbConnection conn;
private OleDbCommand command;
private OleDbDataAdapter adapter;
public DalAccess(string strQuery)
{
string ConnectionString = string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database.accdb");
conn = new OleDbConnection(ConnectionString);
command = new OleDbCommand(strQuery, conn);
adapter = new OleDbDataAdapter(command);
}
public DataSet GetDataSet(string strSql)
{
DataSet ds = new DataSet();
command.CommandText = strSql;
adapter.SelectCommand = command;
adapter.Fill(ds);
return ds;
}
public int InsertUpdateDelete(string strSql)
{
int rowsAffected;
this.conn.Open();
OleDbCommand cmd = new OleDbCommand(strSql, conn);
rowsAffected = cmd.ExecuteNonQuery();
conn.Close();
return rowsAffected;
}
}
Note: i am a complete beginner and have no idea what does anything in that code means.
So, i wrote these lines of code in the aspx.cs page behind
{
public DataSet ds ;
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack) {
string loginid = Request.Form["loginid"];
string loginpw = Request.Form["loginpw"];
string sqlS = "Select IDD,Pass from UserInfo where IDD = '"+ loginid + "'";
DalAccess dal = new DalAccess(sqlS);
ds = dal.GetDataSet(sqlS);
}
}
}
And if i wrote it correctly i selected the two tabs of the row that the value of IDD(ID of the user) in the table is loginid.
Problem is, i can't figure out how to take that data i selected and compare it to the things entered into the inputs and to check if they match.
I'd greatly appreciate if someone were to go as far as explain to me what everything does, since my teacher hasn't got a lot of time to give to all the students, but an example and a simple explanation will work for me too.
Important note!: I know if i make it parameterized it is safe against sql injection, which i did not do, but this part of the project is not for the purpose of security, which we will have a part for it too, and we will learn.
Thanks in advance.

when water rises above the level of the noses, only those will survive, who know how to swim, isn’t it?
Technically we will go for stored procedure to validate the login[as best practices].In the link the its very clear that you can do it with minimal coding.
How to validate login and pass userID
Updated:
ok, if we want to do it in your way.
In the code behind inside the method
private void ValidateLogin()
{
string uname = "Hsakarp";//I have hard-coded the value to make it simple
string pwd = "12345";
string sqlS = "Select UserName,Password from Login where UserName = '" + uname + "' and Password = " + pwd;
DalAccess dal = new DalAccess();
DataSet ds = dal.GetDataSet(sqlS); //GetDataset is gonna return the ds
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
if (ds.Tables[0].Rows[i]["UserName"].ToString().Trim() == uname && ds.Tables[0].Rows[i]["Password"].ToString().Trim() == pwd)
//Check whether the username and password exists.
Label1.Text = "Login Successfull";
else
Label1.Text = "Login failed";
}
}

Related

WHERE Name='{NameInput.Text}' AND Password='{GetHashString(PasswordInput.Text)} not working

I'm trying to get my LoginButton to work, it isn't really doing what I want it to do.
I already have a RegisterButton which works perfectly and creates the account without any problems, but when trying to do my LoginButton it connects to the database but doesn't really check if the account exists using selectQuery and it should change WarningLabel.Text to "Wrong Name or Password". it does go through the first try and changes the WarningLabel.Text to "Welcome " + NameInput.Text;
private void LoginButton_Click(object sender, System.EventArgs e)
{
string selectQuery = $"SELECT * FROM bank.user WHERE Name='{NameInput.Text}' AND Password='{GetHashString(PasswordInput.Text)}';";
MySqlCommand cmd;
connection.Open();
cmd = new MySqlCommand(selectQuery, connection);
try
{
cmd.ExecuteNonQuery();
WarningLabel.Text = "Welcome " + NameInput.Text;
} catch
{
WarningLabel.Text = "Wrong Name or Password";
}
connection.Close();
}
Best Regards - Nebula.exe
The ExecuteNonQuery is not intented to be used with SQL statements that return data, you should use ExecuteReader or ExecuteScalar, you can check the MySqlCommand.ExecuteReader documentation
Warning: Your code does have a SQL Injection vulnerability in this part of the SQL statement Name='{NameInput.Text}' Check this SQL Injection explanation
Usage example (from the documentation, slightly modified):
using (MySqlConnection myConnection = new MySqlConnection(connStr))
{
using (MySqlCommand myCommand = new MySqlCommand(mySelectQuery, myConnection))
{
myConnection.Open();
MySqlDataReader myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine(myReader.GetString(0));
}
}
}
You should check if there are records returned. cmd.ExecuteNonQuery(); won't tell you if records are returned because it will just execute the query. You should use ExecuteScalar or a MySQL Data Reader ExecuteReader and track the results.
Note : Your code is prone to SQL Injections, you might want to use Parameters in your query like #name and #password.
Your Query goes something like this.
string selectQuery = $"SELECT IFNULL(COUNT(*),0) FROM bank.user WHERE Name=#name AND Password=#password;";
Then use parameters
cmd.parameters.AddWithValue(#name, NameInput.Text);
cmd.parameters.AddWithValue(#password, GetHashString(PasswordInput.Text));
Then verify if the query returns result
If cmd.ExecuteScalar() > 0
//If count is > 0 then Welcome
//Else Wrong username or password
End If
Your life, made easy:
private void LoginButton_Click(object sender, System.EventArgs e)
{
var cmd = "SELECT * FROM bank.user WHERE Name=#name AND Password=#pw";
using var da = new MySqlDataAdapter(cmd, connection);
da.SelectCommand.Parameters.AddWithValue("#name", NameInput.Text);
da.SelectCommand.Parameters.AddWithValue("#pw",GetHashString(PasswordInput.Text));
var dt = new DataTable();
da.Fill(dt);
if(dt.Rows.Count == 0)
WarningLabel.Text = "Wrong Name or Password";
else
WarningLabel.Text = $"Welcome {dt.Rows[0]["FullName"]}, your last login was at {dt.Rows[0]["LastLoginDate"]}";
}
Your life, made easier (with Dapper):
class User{
public string Name {get;set;} //username e.g. fluffybunny666
public string FullName {get;set;} //like John Smith
public string Password {get;set;} //hashed
public DateTime LastLoginDate {get;set;}
}
//or you could use a record for less finger wear
record User(string Name, string FullName, string Password, DateTime LastLoginDate);
...
using var c = new MySqlConnection(connection):
var u = await c.QuerySingleOrDefaultAsync(
"SELECT * FROM bank.user WHERE Name=#N AND Password=#P",
new { N = NameInput.Text, P = GetHashString(PasswordInput.Text)}
);
if(u == default)
WarningLabel.Text = "Wrong Name or Password";
else
WarningLabel.Text = $"Welcome {u.FullName}, your last login was at u.LastLoginDate";

Forms app wont accept my SQL table column with usernames, but it will accept the password

I'm creating a forms application which needs a login function. I have set up the MySqL connection and have applied it to my form. It does answer to my to responses, giving me a respons with a pass or no pass, BUT this is only when I ask for it to only match the input with passwords in the database. I cannot get it to match both the usernames and the passwords, even though I seem to have configurated my table as it should be. I've got 3 columns with ID, username(brugernavn) and password.
I can get it to accept both credentials if I match the ID's with the right password, fx SELECT * FROM bruger WHERE password =#pass AND id=#usn
I'm still very new to programming so if I'm confused please let me know.
Is anyone able to help?
I've tried to change my parameters to something else, but that didnt do the trick. There didnt seem to be a problem with the actual table, as it could acces my information about the passwords and the ID's, so I tried changing some values and stuff from the username column, but it did no good. I have both the username and password using varchar(100) and the ID is using INT(11) as a primary.
MySqlConnection connection = new MySqlConnection("server=localhost;port=3306;username=root;password=;database=bruger");
public void openConnection()
{
if (connection.State == System.Data.ConnectionState.Closed)
{
connection.Open();
}
}
public void closeConnection()
{
if (connection.State == System.Data.ConnectionState.Open)
{
connection.Close();
}
}
public MySqlConnection GetConnection()
{
return connection;
}
private void Loginbutton_Click(object sender, EventArgs e)
{
DB db = new DB();
string username = textBoxBrugernavn.Text;
string password = textBoxPassword.Text;
DataTable table = new DataTable();
MySqlDataAdapter adapter = new MySqlDataAdapter();
MySqlCommand command = new MySqlCommand("SELECT * FROM bruger WHERE password =#pass AND brugernavn =#usn", db.GetConnection());
command.Parameters.Add("#usn", MySqlDbType.VarChar).Value = username;
command.Parameters.Add("#pass", MySqlDbType.VarChar).Value = password;
adapter.SelectCommand = command;
adapter.Fill(table);
if (table.Rows.Count > 0)
{
MessageBox.Show("YES");
}
else
{
MessageBox.Show("NO");
}
I was hoping this would let me run my forms apps and then let me login with already created users in my database. This however is not the case, as I am unable to match these two informations in the application.
Keep you data objects local. Then you can be sure they are closed and disposed. The using blocks take care of that even if there is an error. Since we only need one piece of data (the count) we can use ExecuteScalar which returns the first column of the first row in the result set. Of course, in a real application, you would never store passwords as plain text. They would be salted and hashed.
private void Loginbutton_Click(object sender, EventArgs e)
{
Int64 RecordCount = 0;
using (MySqlConnection cn = new MySqlConnection("server=localhost;port=3306;username=root;password=;database=bruger"))
{
using (MySqlCommand command = new MySqlCommand("SELECT Count(*) FROM bruger WHERE password =#pass AND brugernavn =#usn", cn))
{
command.Parameters.Add("#usn", MySqlDbType.VarChar).Value = textBoxBrugernavn.Text;
command.Parameters.Add("#pass", MySqlDbType.VarChar).Value = textBoxPassword.Text;
cn.Open();
RecordCount = (Int64)command.ExecuteScalar();
}
}
if (RecordCount > 0)
{
MessageBox.Show("YES");
//Add code to proceed to your next form
}
else
{
MessageBox.Show("NO");
}
}

SQL query output not viewing on textbox

My output on SQL query is not viewing on my textbox, when the form load it must be automatically inserted to my textbox. The only output on my textbox is System.Data.SqlClient.SqlCommand
I don't know whats wrong or missing on my codes. Please help me, sorry I'm just a newbie on c#
Any type of response is greatly appreciated. Thank you in advance.
private void EmailGen_Load(object sender, EventArgs e)
{
connect.Open();
string emailto = "select emailaddress from emails where password = ''";
string emailfr = "select emailaddress from emails where password != null";
SqlCommand emailt = new SqlCommand(emailto, connect);
SqlCommand emailf = new SqlCommand(emailfr, connect);
emailt.ExecuteNonQuery();
txBEmailRec.Text = emailt.ToString();
txBEmailFr.Text = emailf.ToString(); ;
connect.Close();
// TODO: This line of code loads data into the 'kwemDataSet.tblProducts' table. You can move, or remove it, as needed.
this.tblProductsTableAdapter.Fill(this.kwemDataSet.tblProducts);
}
You should use ExecuteScalar(); instead of ExecuteNonQuery(); And also, you code seems to missing to execute emailf SqlCommand.
You could see this reference as well.
private void EmailGen_Load(object sender, EventArgs e)
{
connect.Open();
string emailto = "select emailaddress from emails where password = ''";
string emailfr = "select emailaddress from emails where password != null";
SqlCommand emailt = new SqlCommand(emailto, connect);
SqlCommand emailf = new SqlCommand(emailfr, connect);
txBEmailRec.Text = emailt.ExecuteScalar().ToString();
txBEmailFr.Text = emailf.ExecuteScalar().ToString();
connect.Close();
// TODO: This line of code loads data into the 'kwemDataSet.tblProducts' table. You can move, or remove it, as needed.
this.tblProductsTableAdapter.Fill(this.kwemDataSet.tblProducts);
}

Getting two DataFields from SQL into the Text of a dropdownlist

I am trying to make it so that I can get two pieces of data from SQL Server into the Text Field of a drop down list. So if I get the data AccountID='1','2' and CompanyName='Build it inc','It ltd'. I want it to display:
1-Build it inc
2-It ltd
I can get the data from sql and get the DataValueField to AccountID but how do I display it. Here is my aspx.
<asp:DropDownList ID="DDLTemplates" DataValueField="AccountID"
DataTextField='<%#Eval("AccountID") + "-" + Eval("CompanyName")%>'
runat="server"></asp:DropDownList>
How do I do this?
Edit: Since alot of you are asking here is my code behind. Thanks for all the Help
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DDLTemplates.DataSource = GetItems();
DDLTemplates.DataBind();
}
}
public DataSet GetItems()
{
String conn = ConfigurationManager.ConnectionStrings["LiquidusConnectionString"].ConnectionString;
SqlConnection sqlConnection2 = new SqlConnection(conn);
string oString = "Select AccountID, CompanyName from Account";
SqlCommand cmd = new SqlCommand(oString);
cmd.Connection = sqlConnection2;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
sqlConnection2.Open();
da.Fill(ds);
sqlConnection2.Close();
return ds;
}
Answer Edit: psoshmo and ragerory Have found the Answer to my question. Here is my code now that it works:
<asp:DropDownList ID="DDLTemplates" DataValueField="AccountID" DataTextField="Company" runat="server"></asp:DropDownList>
Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DDLTemplates.DataSource = GetItems();
DDLTemplates.DataBind();
}
}
public DataSet GetItems()
{
String conn = ConfigurationManager.ConnectionStrings["LiquidusConnectionString"].ConnectionString;
SqlConnection sqlConnection2 = new SqlConnection(conn);
string oString = "SELECT AccountID, (Convert(varchar,AccountId) + ' - ' + CompanyName) as company FROM Account";
SqlCommand cmd = new SqlCommand(oString);
cmd.Connection = sqlConnection2;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
sqlConnection2.Open();
da.Fill(ds);
sqlConnection2.Close();
return ds;
}
Hope this helps future googler's :)
Based on your GetItems method, you can change the oString variable...
string oString = "SELECT AccountID, (Convert(varchar,AccountId) + ' - ' + CompanyName) as Company FROM Account";
And then change your control to the following
<asp:DropDownList ID="DDLTemplates" DataValueField="AccountID" DataTextField="Company" runat="server"></asp:DropDownList>
You're concatenating the two fields and making them one column called Company so that's what you should have as the TextField.
Simply Create a field in your class that adds these together, and bind that to the DataTextField
something like:
public string YourFieldNameHere
{
get { return String.Format("{0} - {1}", AccountID, CompanyName); }
}
EDIT: My bad for assuming you had a class file setup. In general, you should avoid having methods like GetItems() in your code for the web page. If you have to get those same records in another page, you will end up duplicating your code, which is bad practice. I would recommend you consider setting up class files to handle select statements like this, as well as other fields and methods you may need.

Check if Column Value Exists in Dataset using C# and ASP

I've tried various solutions I have found and either I don't know how to implement them properly or they simply won't work. I have a method that allows someone to search a table for a specific order number, then the rest of the row will display in a gridview. However, if an order number is entered that doesn't exist in the table then I can get server error/exception. How can I make it so that before the search goes through or while the search goes through, if an order number that does't exist in the database is searched for then I can create the error instead?
I am using an ms access database, C#, and ASP.
Here is some of the code I am working with:
the method for searching the order table:
public static dsOrder SearchOrder(string database, string orderNum)
{
dsOrder DS;
OleDbConnection sqlConn;
OleDbDataAdapter sqlDA;
sqlConn = new OleDbConnection("PROVIDER=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + database);
DS = new dsOrder();
sqlDA = new OleDbDataAdapter("select * from [Order] where order_num='" + orderNum + "'" , sqlConn);
sqlDA.Fill(DS.Order);
return DS;
}
And using that method:
protected void btnSearch_Click(object sender, EventArgs e)
{
Session["OrderNum"] = txtSearch.Text;
Session["ddl"] = ddlSearch.Text;
if (Session["ddl"].ToString() == "Order")
{
dsOrder dataSet2;
dataSet2 = Operations.SearchOrder(Server.MapPath("wsc_database.accdb"), Session["OrderNum"].ToString());
grdSearch.DataSource = dataSet2.Tables["Order"];
grdSearch.DataBind();
}
Do I need to do a try/catch?
A huge thanks in advance to who is able to help me!
You can simply do a check to see whether DataSet is empty
if (dataSet2 == null || dataSet2.Tables.Count == 0 || dataSet2.Tables["Order"] == null || dataSet2.Tables["Order"].Rows.Count == 0)
{
//display error to user
}
else
{
// your code to populate grid
}
If you don't want to show error then just put this check before populating GridView
if (dataSet2.Tables != null && dataSet2.Tables["Order"] != null)
{
// your code to populate grid
}
I use a different approach when filling data grids and always use parameters as follows:
public static DataTable GetGridDatasource(string database, string ordnum) {
using (OleDbConnection con = new OleDbConnection("PROVIDER=Microsoft.ACE.OLEDB.12.0;Data Source=" + database))
{
con.Open();
OleDbCommand cmd = con.CreateCommand();
cmd.CommandText = "select * from [Order] where order_num=[OrderNumber]";
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("OrderNumber", ordnum);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
protected void btnSearch_Click(object sender, EventArgs e)
{
Session["OrderNum"] = txtSearch.Text;
Session["ddl"] = ddlSearch.Text;
if (Session["ddl"].ToString() == "Order")
{
grdSearch.DataSource = GetGridDatasource(Server.MapPath("wsc_database.accdb"), Session["OrderNum"].ToString());
}
}

Categories