C# Windows Forms Application textbox validation against SQL DB - c#

I'm new to C# and have a background in SQL so apologies if this is a very stupid query, but I have been trawling google for about 2 hours now and can't find what I need. If someone knows of an article they can point me to, that would be great.
I have a simple windows forms application, and I'm setting up a login box so that users have to enter their user ID to proceed.
I have a SQL Server DB (SQL 2005) with the following table:
Users
UserID (int); userName nvarchar(50)
I am using Visual Studio 2010
What I'm stymied by is how to check whether their userID exists in my SQL Table (called users...) I'm not going to put any code here because it's been rewritten from scratch so many times that a clean slate is probably best!
Ideally, I want the user to enter their user ID, and click 'login'. When they do this, if their userID is not valid in the DB table then I need it to give an error msgBox; if it is valid then it should log them in, passing their userID and userName (stored in the DB table) to a variable which I can use elsewhere in the application to populate fields.
I hope this makes sense, and I'm sure I've missed the perfect article out there which will explain it all - hopefully one of you kind people can point me in the right direction!
Thank you

You should make a simple SQL query with the userID the user entered, like
SELECT UserID from Users where userID= value. The executeNonQuery() will return the number of matches. If the returned value ==1, means that the userid exists in the database. If the returned value is different from 1, means that the userid not exists or it was registered multiple times. So, if is 1 then you cand call a different form to make different things, else you call anoter form or output a messagebox with an error message

/*table code
* create table login
(
id varchar(25),
pass varchar(25)
)
*
*
*
*
*/
string Connectstring = #"Data Source=DELL-PC;Initial Catalog=stud;Integrated Security=True";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SqlConnection cn = new SqlConnection(Connectstring);
cn.Open();
SqlCommand cmd = new SqlCommand("select * from log where id=#a and pass=#b", cn);
cmd.Parameters.AddWithValue("#a", textBox1.Text.ToString().ToUpper());
cmd.Parameters.AddWithValue("#b", textBox2.Text);
SqlDataReader dr = cmd.ExecuteReader();
if ((dr.Read() == true))
{
MessageBox.Show("The user is valid!");
Form2 mainForm = new Form2();
mainForm.Show();
this.Hide();
}
else
{
MessageBox.Show("Invalid username or password!");
}
}

Declare a connection string to Your database
string connString = #"Data Source=.\SQLEXPRESS;Initial Catalog=YourDatabase;Integrated Security=True";
After this You can use a validate method below
private bool ValidateUserById(string connString, int id)
{
using (var conn = new SqlConnection(connString))
{
conn.Open();
var sqlString = string.Format("Select * From Users where Id = {0}", id);
using (var cmd = new SqlCommand(sqlString, conn))
{
return cmd.ExecuteScalar() != null;
}
}
}
Then on button click You can check the user
if (ValidateUserById(connString, Convert.ToInt32(textBox1.Text)))
{
//..
}
else
{
//..
}

Related

Compare a value in a table in SQL to an entry in a textbox

I have a table EmployeeRank1 in SQL Server that has a column Name. Under column Name there are two pre-defined names of employees. Moreover, in the table there is a column Password, which contains a generic password, which is "123456".
In WPF I have a textbox and that asks for name and one password box that asks for password. Underneath them, there is a button that says "Login".
The questions is how do I compare the content of Name and Pasword in my table to the input in the text box and the password box?
If the Name entered exists and the Password is correct, a new WPF page will be opened. Otherwise, a message stating that either the name or the password is incorrect will be printed.
This is what I have until now:
// check if the input matches and open the new WPF Page
private void EmployeeRank1Button_Click(object sender, RoutedEventArgs e)
{
try
{
// create a query and select everything from the EmployeeRank1 table
string query = "select * from EmployeeRank1";
// create a connection to the database and run the query
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(query, sqlConnection);
// use the sqlDataAdapter
using(sqlDataAdapter)
{
// create a new DataTable that allows us
// to store data from tables within objects
DataTable employeeRank1Table = new DataTable();
// fill the sqlDataAdapter with all the
// information from the query(from the employeeRank1Table)
sqlDataAdapter.Fill(employeeRank1Table);
// TODO: compare Name and Password entered in the TextBox and PasswordBox to the data in the table
if (tbName.Text == *Name in Table* && pbPassword.Password == *Password in Table*)
{
EmployeeRank1 employeeRank1 = new EmployeeRank1();
employeeRank1.Show();
}
}
}
catch(Exception exception)
{
MessageBox.Show(exception.ToString());
}
}
You don't need to retrieve the whole table in memory. Just use a WHERE statement in your sql command with Name = #nameparam AND Password = #passparam, use an SqlCommand to retrieve a SqlDataReader and if the reader has a row, then bingo, the user exists.
Said that, remember that storing passwords in clear text is a big NO NO in a security concerned application. See this q/a for the reasons
private void EmployeeRank1Button_Click(object sender, RoutedEventArgs e)
{
try
{
// create a query and select just the record we need
string query = "select * from EmployeeRank1 where Name = #name AND Password = #pass";
// A local sqlconnection in a using statement ensure proper disposal at the end of this code
using SqlConnection con = new SqlConnection(connectionstring);
con.Open();
// Let's the database do the work to search for the password and name pair
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = tbName.Text ;
cmd.Parameters.Add("#pass", SqlDbType.NVarChar).Value = tbPassword.Text ;
SqlDataReader reader = cmd.ExecuteReader();
// If the reader has rows then the user/pass exists in the db table
if(reader.HasRows)
{
EmployeeRank1 employeeRank1 = new EmployeeRank1();
employeeRank1.Show();
}
}
catch(Exception exception)
{
MessageBox.Show(exception.ToString());
}
}
Note also that I used a local SqlConnection and not a global one inside a using statement. This is the correct way to use a Disposable object like a connection. Keeping a global connection is prone to resource leaks and all sorts of problems if something fails.

Check if for username and password the type is for a client or for a administrator

I just finished a database in C# with SQL. In my database I add data when I create the account for a person. I add the username, password, first and last name and the type (client or administrator).
When I am logging in all what I do is to check if username and password are correct. Here is the code.
private void button1_Click(object sender, EventArgs e)
{
con = new SqlConnection(#"Data Source=MARIA-PC;Initial Catalog=Account;Integrated Security=True");
SqlCommand cmd1 = new SqlCommand("SELECT * FROM [dbo].[Cont] WHERE Username = #Username and Password = #Password;", con);
cmd1.Parameters.AddWithValue("#Username", this.Username.Text);
cmd1.Parameters.AddWithValue("#Password", this.Password.Text);
cmd1.Connection = con;
con.Open();
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(cmd1);
da.Fill(ds);
con.Close();
bool loginSuccessful = ((ds.Tables.Count > 0) && (ds.Tables[0].Rows.Count > 0));
if (loginSuccessful )
{
MessageBox.Show("You logged in successfully!","Success!");
this.Visible = false;
f3.ShowDialog();
this.Visible = true;
}
else
{
MessageBox.Show("Invalid username or password!", "Error!");
}
}
And next what I want to do is to check if for this username and password the type is for client or administrator. And if is for administrator to entry in a form or if is for client to entry in another form.
How can I do? I need some ideas.
Here is the table:
You are retrieving the full row from your database table, so you have also retrieved the column that contains the usertype. You just need to check it after verifying the login
Here an example assuming that a "1" value means administrator, a "2" means normal user (of course you could change these constants to your actual values)
if (loginSuccessful )
{
string userType = ds.Tables[0].Rows[0]["Type"].ToString();
if(userType == "1")
{
// User is an administrator, go to admin form
}
else if(userType == "2")
{
// User is a normal user, go to user form
}
else
{
// Unexpected value, error message?
}
}
A side note, while you are using parameters there is still a security problem in your database/code logic. It seems that you store your password as a plain text. This could give to anyone that looks at your database table the possibility to know your users passwords. A password should never be stored in plain text. This site contains a lot of answer on how to correctly store passwords in a database
Start from here:
Best way to store passwords in a database

Update if disabled = 0 in C#

I am making a project in C#- in which one can "vote".
When you run the program you first log in. After you've logged in you have to select a value out of a dropdownlist. After you've selected the teacher you press on a button which votes.
The problem is I don't really know how to let this validate properly. And to check if the person has already voted.
It has to check the column in the database named "disabled" if the value = 1 or 0. If the value = 1 they can't vote and if it's 0 they can.
When the person votes it increases the column aantalStemmen by 1. and the disabled column to 1 aswell. Which gets shown in a datagridview.
And the values in the dropdownlist has to match the 1 in the database.
I have this code:
private void db_connection()
{
try
{
conn = "Data Source=localhost;Initial Catalog=docent;Integrated Security=True";
connect = new SqlConnection(conn);
connect.Open();
}
catch (SqlException e)
{
throw;
}
}
private bool validate_disabled(string favoriet)
{
db_connection();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "Select disabled from leerling";
cmd.Connection = connect;
SqlDataReader disabled = cmd.ExecuteReader();
if (disabled.Read())
{
connect.Close();
return true;
}
else
{
connect.Close();
return false;
}
}
private void btnStem_Click(object sender, EventArgs e)
{
string favoriet = cmbFavoriete.Text;
db_connection();
SqlCommand cmd = new SqlCommand();
bool r = validate_disabled(favoriet);
if(r){
cmd.CommandText = "UPDATE docent SET aantalStemmen = aantalStemmen + 1 where docentid=#id";
cmd.Parameters.AddWithValue("#id", cmbFavoriete.Text);
}
else
{
MessageBox.Show("You have already voted.");
}
}
my tables in my database looks like this:
Thanks in advance, I've been struggling really hard with this as I'm still a rookie in C#.
I will try an answer to cover more aspects of your code (many already mentioned in comments):
1) Declare your connection string outside of your methods. Also choose meaningful variable names - you will than yourself in a few months when you revisit the code.
private const String ConnectionStr = "Data Source=localhost;Initial Catalog=docent;Integrated Security=True";
2. Appropriate names for methods - also, try to use Camel or Pascal case for method names.
3. Pay attention to possible exceptions. SQLException is not the only possible exception when constructing or opening an SqlConnection, so it is better to catch anything that might occur
private SqlConnection createConnection
{
try
{
connect = new SqlConnection(ConnectionStr);
connect.Open();
}
// this is laziness, but it is better than before
catch (Exception e)
{
// best to log the real error somewhere
throw;
}
}
4. Dispose connection and other disposables like SqlCommand. Also var might save some typing (just hover your mouse over the keyword and you will see the actual type).
SqlConnection allows to directly create a command to be executed using that particular connection by using CreateCommand.
Since your are expecting a single value (scalar) (or a single row with a single column), you can use ExecuteScalar method. So, no more reader.
private bool isDisabled(string favoriet)
{
using (var connection = createConnection())
{
using (var cmd = new connection.CreateCommand())
{
cmd.CommandText = "Select disabled from leerling where leerlingnummer = #number";
cmd.Parameters.AddWithValue("#number", favoriet);
// for simplicity I have assumed that it will always find a value. This should be checked
var disabled = Convert.ToBoolean(cmd.ExecuteScalar());
return disabled;
}
}
}
5. Try not to mix UI logic with database logic (they are usually put in different assemblies)
private void castVote(String favoriete)
{
using (var connection = createConnection())
{
using (var cmd = new connection.CreateCommand())
{
cmd.CommandText = "UPDATE docent SET aantalStemmen = aantalStemmen + 1 where docentid = #id";
cmd.Parameters.AddWithValue("#id", cmbFavoriete.Text);
// command must be actually executed, otherwise nothing happens
cmd.ExecuteNonQuery();
}
}
}
private void btnStem_Click(object sender, EventArgs e)
{
string favoriet = cmbFavoriete.Text;
bool r = isDisabled(favoriet);
if (r)
castVote(favoriet);
// maybe, it would make sense to also notify the user that the vote has been cast
else
MessageBox.Show("You have already voted.");
}
6. Use EntityFramework - in order to avoid the troubles related to handling commands and readers, you can use an ORM to do the dirty work for you.
I would suggest you use bit Data Type (0 - false, 1 - true) instead of int Data Type in your table. It does exactly what you need and you don't have to use int for this.
This means you could change your validate_disabled method to use something like this:
cmd.CommandText = "SELECT disabled FROM leerling WHERE disabled = 1 AND leerlingnummer = #favoriet";
cmd.Parameters.AddWithValue("#favoriet", favoriet);
I've assumed string favoriet is equal to leerlingnummer in your table. After you've executed that query, you would simply check if the query contains more than 0 records - if more than 0 records that means the person does not have permission to vote.

C# - New Values not reflecting on Access Database using UPDATE SQL cmd

I'm having problems with updating a row in the Users table of my Access DB. Here is the code below:
private void SaveProfileInfo()
{
try
{
ChangeForeColorOfStatusMsg(Color.Black);
ChangeTextOfStatusMsg("Saving new profile information...");
const string cmd = #"UPDATE Users SET LastName=#LastName,FirstName=#FirstName,MiddleName=#MiddleName,Add_Num=#Add_Num,Add_Street=#Add_Street,Add_Brgy=#Add_Brgy,Add_City=#Add_City,MobileNumber=#MobileNumber,Gender=#Gender WHERE ID=#ID;";
var dbConn = new OleDbConnection(cs);
var dbCmd = new OleDbCommand(cmd, dbConn);
dbCmd.Parameters.AddWithValue("#ID", UserLoggedIn.ID);
dbCmd.Parameters.AddWithValue("#LastName", txtLastName.Text);
dbCmd.Parameters.AddWithValue("#FirstName", txtFirstName.Text);
dbCmd.Parameters.AddWithValue("#MiddleName", txtMiddleName.Text);
dbCmd.Parameters.AddWithValue("#Add_Num", txtUnitNum.Text);
dbCmd.Parameters.AddWithValue("#Add_Street", txtStreet.Text);
dbCmd.Parameters.AddWithValue("#Add_Brgy", GetBrgySelectedItem());
dbCmd.Parameters.AddWithValue("#Add_City", GetCitySelectedItem());
dbCmd.Parameters.AddWithValue("#MobileNumber", txtMobileNumber.Text);
dbCmd.Parameters.AddWithValue("#Gender", GetGenderSelectedItem());
dbConn.Open();
dbCmd.ExecuteNonQuery();
dbConn.Close();
ChangeForeColorOfStatusMsg(Color.MediumSeaGreen);
ChangeTextOfStatusMsg("All changes have been saved! This window will close itself after two seconds.");
Thread.Sleep(2000);
CloseForm();
}
catch (Exception)
{
ChangeForeColorOfStatusMsg(Color.Crimson);
ChangeTextOfStatusMsg("Something went wrong while we were connecting to our database. Please try again later.");
hasFinishedEditting = false;
}
}
This method will be done on a separate thread, when the user updates his profile information.
UserLoggedIn is actually a field of a User class (a class that defines a row in my table), which stores all the info of the user who's currently logged in.
When I run this, it does not produce any exceptions or errors. But when I check my table, the values are not updated.
I copy-pasted these codes from the registration form (which works) that I made with this system, and modified it into an UPDATE cmd than an INSERT cmd.
I also made Change Username and Password Forms that use the same cmd as shown below:
public void ChangePass()
{
try
{
ChangeForeColorOfMsg(Color.Silver);
ChangeTextOfMsg("Changing password...");
const string cmd = "update Users set Pass=#Pass where ID=#ID";
var dbConn = new OleDbConnection(cs);
var dbCmd = new OleDbCommand(cmd, dbConn);
dbCmd.Parameters.AddWithValue("#Pass", txtNewPass.Text);
dbCmd.Parameters.AddWithValue("#ID", UserLoggedIn.ID);
dbConn.Open();
dbCmd.ExecuteNonQuery();
dbConn.Close();
ChangeTextOfMsg("Password successfully changed!");
}
catch (Exception)
{
ChangeForeColorOfMsg(Color.Silver);
ChangeTextOfMsg("A problem occurred. Please try again later.");
}
}
And these codes work for me. So I'm really confused right now as to why this update cmd for the profile information isn't working... Is there something I'm not seeing here?
OleDb cannot recognize parameters by their name. It follows a strictly positional order when sending them to your database for updates. In your code above the first parameter is the #ID but this parameter is used last in your query. Thus everything is messed up.
You just need to move the add of the #ID parameter as last in the collection
As a side note, you should be very careful with AddWithValue. It is an handy shortcut, but it has a dark side that could result in wrong queries.
Take a look at
Can we stop using AddWithValue already?

Adapt beginner C# SQL Server INSERT example to work with my database

I have read TONS of tutorials, articles and whatever regarding my issue and honestly, due to my lack of experience I can't twist my fingers around this one so I hope some of you guys can help me out :)
I am working on a project (simply to learn how to program so it's probably very basic), but I have this "News" page where I can update and delete data using a GridView.
Now I would like to INSERT something into my database using 3 textboxes and 1 submit button.
I have 3 rows that has to be inserted:
Headline
Date
Content/the news itself.
Which are stored under NyhedTB from the connectionstring: BoligStjernenConnectionString
My query looks like this:
INSERT INTO [NyhedTB] ([NyhedDato], [NyhedTitel], [NyhedTekst])
VALUES (#NyhedDato, #NyhedTitel, #NyhedTekst)
I read on the internet that this code should do the magic for me (I will have to insert my own values ofc.):
static void Insert()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("INSERT INTO EmployeeDetails VALUES(" +
"#Id, #Name, #Address)", conn))
{
cmd.Parameters.AddWithValue("#Id", 1);
cmd.Parameters.AddWithValue("#Name", "Amal Hashim");
cmd.Parameters.AddWithValue("#Address", "Bangalore");
int rows = cmd.ExecuteNonQuery();
//rows number of record got inserted
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}
I looked at this code and thought it should be easy enough but really, I can't figure it out.
Here is some advice to get you going, learning programming is a lot of
trial and error.
Start off basic, litrally put three textboxes on a form/page and a
button.
Double click the button to go the code-behind and view the buttons
click event.
Paste in the body of code included with your question (everything in the try-catch).
Put a break-point on the Public Void Button_Click line of code and press F11 to
step through the code.
"one thing is having the code-behind working but how to make the buttons and textboxes working is still a misery"*
Put the textbox as the value rather than your hardcoded values:
cmd.Parameters.AddWithValue("#Address", textBox1.Text);
You also should not insert the Id value, instead modify the EmployeeDetails table and set the ID column to in the properties set Identity Specification (IS Identity) = True. Then right click the ID column and set Primary Key.
Post any error messages you encounter here and when you do get get it working, an additional exercise (that will be very valuable for you) would use a database stored procedure rather than ad-hoc SQL, to safe-guard against sql-injection attacks.
I'm assuming you have SQL Server installed and have a 'employee' database with a table called EmployeeDetails.
protected void GvManualShows_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//label lbl = (label)e.Row.FindControl("lblHidden");
if (e.Row.Cells[14].Text == "Y")
{
// CheckBox cb = (CheckBox)e.Row.FindControl("chk");
CheckBox chk = (CheckBox)e.Row.Cells[0].FindControl("chkBox");
chk.Checked = true;
}
}
}
It's fairly simple. You just have to modify the connection string, the query and its parameters:
private void button1_Click(object sender, EventArgs e)
{
try
{
string connectionString =
"server=SQLServer;" + // SQLServer is your SQL server machine
"initial catalog=employee;" + // employee is your database
"user id=sa;" + // sa is the login to connect the database
"password=sa123"; // sa123 is the password of the login
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(
"INSERT INTO [NyhedTB] ([NyhedDato], [NyhedTitel], [NyhedTekst]) " +
"VALUES (#NyhedDato, #NyhedTitel, #NyhedTekst)", conn))
{
cmd.Parameters.AddWithValue("#NyhedDato", textBoxDate.Text);
cmd.Parameters.AddWithValue("#NyhedTitel", textBoxTitle.Text);
cmd.Parameters.AddWithValue("#NyhedTekst", textBoxBody.Text);
int rows = cmd.ExecuteNonQuery(); // Inserted rows number
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}
I made changed example code with your requirements and added comments, hope it would be a bit clearer for you to understand whats going on:
static void Insert()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=MyDatabaseName;" + //here you write database name where your NyhedTB table is
"user id=sa;" + //user name to connect to database
"password=sa123"; //password
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("INSERT INTO NyhedTB (NyhedDato, NyhedTitel, NyhedTekst) VALUES (#NyhedDato, #NyhedTitel, #NyhedTekst)", conn))
{
//all "things" in your sql command what beggins with #
//means that it is parameter and you need to pass values for these parameters:
//For #NyhedDato parameter you set text from your textbox
cmd.Parameters.AddWithValue("#NyhedDato", txtDate.Text);
//For #NyhedTitel parameter you set text from title textbox
cmd.Parameters.AddWithValue("#NyhedTitel", txtTitle.Text);
//For #NyhedTekst parameter you set text from content textbox
cmd.Parameters.AddWithValue("#NyhedTekst", txtContent.Text);
//Execute insert command and get how many records was efected, in this case it should be rows = 1 because you inserting just one record
int rows = cmd.ExecuteNonQuery();
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}
P.s. code not tested. And when you say
I have 3 rows that has to be inserted:
Headline
Date
Content/the news itself.
actually you mean you want to insert record with fields

Categories