Declare SQL result as variable - c#

I need to send the ID of a logged in user to multiple windows forms but can't figure it out. How can I call the variable on multiple forms?
private void btnUpdate_Click(object sender, EventArgs e)
using(var con = new SqlConnection("connectionstring"))
{
var query = "SELECT TOP 1 ID FROM users WHERE username = #username AND password = #password";
// Build a command to execute your query
using(var cmd = new SqlCommand(con,query))
{
// Open connection
con.Open();
// Add your parameters
cmd.Parameters.AddWithValue("#username", txtUsername.Text);
cmd.Parameters.AddWithValue("#password", txtPassword.Text);
// Get ID
var sqlid = Convert.ToInt32(cmd.ExecuteScalar());
}
}
Ive been stumped for hours and can't proceed

How can I call the variable on multiple forms?
Take the code out of your button click event. Put it in a class within a shared library that can be accessed by multiple forms.
You should also create a User class (and a UserRepository) that you pass around instead of just an ID with no context.

This is what D Stanley was talking about.
The User data-structure
public class MyUser
{
public int ID;
public string UserName;
public MyUser(int id, string userName)
{
ID = id;
UserName = userName;
}
}
The database interface class
public class UserContext
{
private ConnectionString = ""
// 1st constructor you pass in connection string.
public UserContext(string connectionString)
{
ConnectionString = connectionString;
}
// 2nd constructor you use the one in the web.config file.
public UserContext()
{
ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["connectionStringName"].ConnectionString;
}
public int GetUserID(string userName, string password)
{
// declare the result variable.
MyUser result
using(var con = new SqlConnection(ConnectionString))
{
var query = "SELECT TOP 1 ID FROM users WHERE username = #username AND password = #password";
// Build a command to execute your query
using(var cmd = new SqlCommand(con,query))
{
// Open connection
con.Open();
// Add your parameters
cmd.Parameters.AddWithValue(userName);
cmd.Parameters.AddWithValue(password);
// Get ID
var sqlid = Convert.ToInt32(cmd.ExecuteScalar());
result = new MyUser(sqlid, userName);
}
}
return result;
}
}
Now all you have to do is create a database context object and pass in properties.
private void btnUpdate_Click(object sender, EventArgs e)
{
// database context.
UserContext UC = new UserContext();
// Get user.
MyUser currentUser = UC.GetUserID(txtUserName.Text, txtPassword.Text);
// now you can access userid from the User data-structure object.
var id = currentUser.ID;
}

Related

Why can't i save registered users to the database?

So i have been trying to resolve this issue for a while now, with no awail. Everything works but when i try to login with a "succesfully registered user", it still shows invalid credentials, meaning that the save didn't succeed,
This is my code:
using System;
using System.Data.SqlClient;
using System.Windows.Forms;
namespace SchoolManagementApplication
{
public partial class LoginDialog : Form
{
public LoginDialog()
{
InitializeComponent();
}
private bool VerifyUserCredentials(string username, string password)
{
bool isValidUser = false;
// Connection string
string connectionString = Properties.Settings.Default.UnPConnectionString;
// SQL query
string query = "SELECT COUNT(*) FROM [Table2] WHERE Username = #Username AND Password = #Password";
// Create a new connection
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create a new command
using (SqlCommand command = new SqlCommand(query, connection))
{
// Add parameters to the query
command.Parameters.AddWithValue("#Username", username);
command.Parameters.AddWithValue("#Password", password);
// Open the connection
connection.Open();
// Execute the query
int result = (int)command.ExecuteScalar();
// Check if the result is greater than 0
if (result > 0)
{
isValidUser = true;
}
connection.Close();
}
}
return isValidUser;
}
public void AddUser(string username, string password)
{
string connectionString = "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\shayan.homaiesfahan\\Desktop\\SchoolManagementApplication\\SchoolManagementApplication\\bin\\Debug\\Unp.mdf;Integrated Security=True";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// insert the new user into the table
string insertSql = "INSERT INTO [Table2] (Username, Password) VALUES (#Username, #Password)";
using (SqlCommand insertCommand = new SqlCommand(insertSql, connection))
{
insertCommand.Parameters.AddWithValue("#Username", username);
insertCommand.Parameters.AddWithValue("#Password", password);
insertCommand.ExecuteNonQuery();
}
connection.Close();
}
}
private void BtnOK_Click(object sender, EventArgs e)
{
// Get the entered username and password
string username = tbxUsername.Text;
string password = tbxPassword.Text;
// Verify the user credentials
if (VerifyUserCredentials(username, password))
{
MessageBox.Show(string.Format("Welcome: {0}", username));
// Code to open the main application goes here
this.Hide();
MainInterface MI = new MainInterface();
MI.Show();
}
else
{
MessageBox.Show("Invalid credentials. Please try again.");
//// Clear the textboxes
tbxUsername.Text = "";
tbxPassword.Text = "";
}
}
private void Btn_register_Click(object sender, EventArgs e)
{
string username = tbxUsername.Text;
string password = tbxPassword.Text;
// Verify that the username and password are not empty
if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
{
// Call the AddUser method
AddUser(username, password);
// Show a message that the user has been registered
MessageBox.Show("You have been successfully registered!");
// Clear the textboxes
tbxUsername.Text = "";
tbxPassword.Text = "";
}
else
{
// Show a message that the username and password are required
MessageBox.Show("Username and password are required.");
}
}
private void btnCancel2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
It did work in one point, but somehow it stopped working.

C# winforms save UserID value to class

I'm trying to save UserID value to a class after an successful login. When the login button is clicked, it validates the login into in text boxes using the #user, #pass.
My problem is that I do not know how to write a sql reader and save the resulting int to a class. I also do not know how to write that class.
I need to save it to a class so I can use it on different forms to check what account the user is logged into.
EDIT: Updated code from suggestions but i get errors Error picture any ideas where i did a mistake?
private LoginUser validate_login(string user, string pass)
{
db_connection();
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "Select * from table2 where username=#user and password=#pass";
cmd.Parameters.AddWithValue("#user", user);
cmd.Parameters.AddWithValue("#pass", pass);
cmd.Connection = connect;
LoginUser usr = new LoginUser();
MySqlDataReader login = cmd.ExecuteReader();
while(login.Read())
{
connect.Close();
usr.UserID = login["UserID"];
usr.valid = true;
}
return usr;
}
private void button1_Click(object sender, EventArgs e)
{
{
string user = usertype.Text;
string pass = password.Text;
if (user == "" || pass == "")
{
MessageBox.Show("Empty Fields Detected ! Please fill up all the fields");
return;
}
bool r = validate_login(user, pass);
if (r)
{
LoginUser usr = new LoginUser();
usr = validate_login(user, pass);
if (usr.valid)
{
Console.WriteLine(String.Format("{0}", usr.UserID));
UserDetails.m_gnUserId = Convert.ToInt32(reader["UserID"]);
}
}
}
}
public partial class Form1 : Form
{
private LoginUser validate_login(string user, string pass)
{
...
LoginUser usr = new LoginUser();
MySqlDataReader login = cmd.ExecuteReader();
while(login.Read())
{
connect.Close();
usr.UserID = login["UserID"];
usr.valid = true;
}
return usr;
}
private void button1_Click(object sender, EventArgs e)
{
...
LoginUser usr = new LoginUser();
usr = validate_login(user, pass);
if (usr.valid)
{
Console.WriteLine(String.Format("{0}", usr.UserID));
}
}
}
public class LoginUser
{
public Bool valid = false;
public String UserID = "";
// You can have more column name up to matching with your table column.
}
One of the method is as follow
Create a class UserDetails with all the data you want to store
public static class UserDetails
{
public static int m_gnUserId {get;set;}
//Add other variables which you want to store and use across different forms
}
To Store Value
UserDetails.m_gnUserId = Convert.ToInt32(reader["UserID"]); .
This storing of Value will go after Console.WriteLine(String.Format("{0}", reader["UserID"])); in your button1_click event.
To get the value on other form
int UserId = UserDetails.m_gnUserId;

How to call a method from another class inside a Window?

So I have a Class called "User" in which I have the following method and code:
public void Login()
{
LoginWindow l = new LoginWindow();
if (l.tbxEmail.Text != "" && l.tbxPassword.Text != "")
{
string query = "SELECT * FROM UsersTBL";
l.con.Open();
l.com = l.con.CreateCommand();
l.com.CommandText = query;
SqlDataReader dr = l.com.ExecuteReader();
if (dr.Read())
{
if (dr["Email"].Equals(l.tbxEmail.Text.ToString()) && dr["UserPassword"].Equals(l.tbxPassword.Text.ToString()))
{
AppWindow a = new AppWindow();
a.Show();
}
else
l.lblMissingParameter.Content = "Incorrect Password or Email entered";
}
}
}
And in my LoginWindow I have:
public partial class LoginWindow:Window
{
User u = new User();
private void BtnSignup_Click(object sender, RoutedEventArgs e)
{
u.Login();
}
}
When I try to call my Login method via class instantiation nothing works, why is that? Am I calling it the wrong way?
This should work, although I left comments on things that should be addressed.
User class:
public bool Login(SqlConnection con, string email, string password)
{
const string query = "SELECT 1 FROM UsersTBL WHERE Email = #email AND UserPassword = #password";
if (!string.IsNullOrWhiteSpace(email) && !string.IsNullOrWhiteSpace(password))
{
try
{
con.Open();
var cmd = con.CreateCommand();
cmd.CommandText = query;
//Correct SqlDbTypes if necessary
cmd.Parameters.Add("#email", SqlDbType.VarChar);
cmd.Parameters["#email"].Value = email;
cmd.Parameters.Add("#password", SqlDbType.VarChar);
//Should NOT be storing passwords as plain text in the database
cmd.Parameters["#password"].Value = password;
if (cmd.ExecuteScalar() == 1)
return true;
}
catch (Exception e)
{
//log e somehow or eliminate this catch block
}
finally
{
//Close the connection if still open
if (con != null && con.State != ConnectionState.Closed)
con.Close();
}
}
return false;
}
LoginWindow class:
public partial class LoginWindow : Window
{
private void BtnSignup_Click(object sender, RoutedEventArgs e)
{
var u = new User();
if (u.Login(con, tbxEmail.Text, tbxPassword.Text))
{
AppWindow a = new AppWindow();
a.Show();
}
else
lblMissingParameter.Content = "Incorrect Password or Email entered";
}
}
To clarify, you had this problem because the tbxEmail and tbxPassword variables in your User class where not the same as the ones in your main class.
You should create both variable at class scope:
public class User {
TextBox tbxEmail; // could be strings
PasswordBox tbxPassword;
public User (TextBox tbxEmail, TextBox tbxPassword) {
this.tbxEmail = tbxEmail;
this.tbxPassword = tbxPassword;
}
}
And then:
User user = new User(tbxEmail,tbxPassword);
user.Login();
Or, create a static method (static method can't use global variables, so everything you need have to be passed as parameter of the method or created inside of it).:
public static void Login (string email, string password){
// code here
}
I wrote a rudimentary login page for one of my school projects similar to this:
private void signInButton_Click(object sender, EventArgs e)
{
DataProcedures data = new DataProcedures();
User userInfo = new User(usernameTextbox.Text, passwordTextbox.Text);
userInfo.userId = data.verifyUser(userInfo);
if (userInfo.userId != -1)
{
AppWindow a = new AppWindow();
a.Show();
}
else
{
errorLabel.Show();
}
}
public int verifyUser(User userInfo)
{
MySqlConnection conn = new MySqlConnection(connectionString);
int userId = -1;
string returnedUserName;
string returnedPassword;
try
{
conn.Open();
MySqlCommand checkUserNameCmd = conn.CreateCommand();
checkUserNameCmd.CommandText = "SELECT EXISTS(SELECT userName FROM user WHERE userName = #username)";
checkUserNameCmd.Parameters.AddWithValue("#username", userInfo.username);
returnedUserName = checkUserNameCmd.ExecuteScalar().ToString();
MySqlCommand checkPasswordCmd = conn.CreateCommand();
checkPasswordCmd.CommandText = "SELECT EXISTS(SELECT password FROM user WHERE BINARY password = #password AND userName = #username)";//"BINARY" is used for case sensitivity in SQL queries
checkPasswordCmd.Parameters.AddWithValue("#password", userInfo.password);
checkPasswordCmd.Parameters.AddWithValue("#username", userInfo.username);
returnedPassword = checkPasswordCmd.ExecuteScalar().ToString();
if (returnedUserName == "1" && returnedPassword == "1")
{
MySqlCommand returnUserIdCmd = conn.CreateCommand();
returnUserIdCmd.CommandText = "SELECT userId FROM user WHERE BINARY password = #password AND userName = #username";
returnUserIdCmd.Parameters.AddWithValue("#password", userInfo.password);
returnUserIdCmd.Parameters.AddWithValue("#username", userInfo.username);
userId = (int)returnUserIdCmd.ExecuteScalar();
}
}
catch (Exception ex)
{
Console.WriteLine("Exception thrown verifying user: " + ex);
}
finally
{
conn.Close();
}
return userId;
}
Hope this helps.

How to check if Username exists in specific column of database

I'm using C# with an ASP.Net table. I'm trying to check when a user accesses my web app, that their User ID is listed in the column called UserID in a table that is displayed in the web app. If it is not, then I want to redirect them to an error page.
I need this to check when the page is loaded so obviously it needs to be in Page_Load. I just don't know how to call the column in my table and to have it check the User ID.
This is what I have so far:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string UserID = HttpContext.Current.Request.LogonUserIdentity.Name.Substring(4);
SQLUserID();
if (UserID != //'Whatever values are in the UserID column'//)
{
Server.Transfer("ErrorPage.aspx");
}
SQLCmd = SqlDataSource1.SelectCommand;
GridView1.DataBind();
}
}
The string UserID gives me the User ID of the user. SQLUserID() = SELECT UserId FROM Info. I know the way I called that isn't correct but I'm not sure how to do it.
It can help you:
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand check_User_Name ("SELECT COUNT(*) FROM tblUser WHERE (UserID=#UserID)",conn);
check_User_Name.Parameters.AddWithValue("#UserID,UserID);
int userExist=(int)check_User_Name.ExecuteScalar();
if(userExist>0)
{
//Login
}
else
{
Server.Transfer("ErrorPage.aspx");
}
just write your connection string and enjoy it.
So here is how I got it to work below Page_Load
{
string connectionString = "Data Source=###;Initial Catalog=###;Integrated Security=True";
if (!Page.IsPostBack)
{
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand("SELECT COUNT(UserID) from Info WHERE UserID like #UserID", sqlConnection))
{
string UserID = HttpContext.Current.Request.LogonUserIdentity.Name.Substring(4);
sqlCommand.Parameters.AddWithValue("#UserID", UserID);
int userCount = (int)sqlCommand.ExecuteScalar();
if (userCount == 0)
{
Server.Transfer("ErrorPage.aspx");
}
SQLCmd = SqlDataSource1.SelectCommand;
GridView1.DataBind();
}
}
}

UpdateCommand not working?

So I have code that stores an UPDATE query in a string, then I parameter bind the update query and then execute and update it, this is my code:
string query = "UPDATE Users SET first_name = '#firstname' WHERE ID = #id";
updateUserDS.UpdateParameters.Add("id", HTTPContext.Current.Session["ColumnID"].ToString());
updateUserDS.UpdateParameters.Add("firstname", txt_firstname.Text);
updateUserDS.UpdateCommand = query;
updateUserDS.Update();
However when I change my string query to:
string query = "UPDATE Users SET first_name = 'name' WHERE ID = 44";
It works perfectly and updates my table, so I am guessing its something to do with how I have binded the query, does anyone realise anything where I have gone wrong?
BTW: The Session["ColumnID"] is being retrieved perfectly as it states 44 in the stack trace
Remove the single quotes from #firstname:
string query = "UPDATE Users SET first_name = #firstname WHERE ID = #id";
updateUserDS.Parameters.AddWithValue("#firstname", first_name);
updateUserDS.Parameters.AddWithValue("#id", HTTPContext.Current.Session["ColumnID"].ToString());
EDIT:
Assuming you are using SQL Server as database try like this:
SqlCommand sqlComm = new SqlCommand();
sqlComm.CommandText = #"UPDATE Users SET first_name = #firstname WHERE ID = #id";
sqlComm.Parameters.Add("#firstname", SqlDbType.VarChar);
sqlComm.Parameters["#firstname"].Value = txt_firstname.Text;
sqlComm.Parameters.Add("#id", SqlDbType.VarChar);
sqlComm.Parameters["#id"].Value = HTTPContext.Current.Session["ColumnID"].ToString();
using (SqlConnection sqlConn = new SqlConnection(connection string here);)
{
sqlComm.Connection = sqlConn;
sqlConn.Open();
sqlComm.ExecuteNonQuery();
}
I'd rewrite this as to use OldDbCommand and OleDbConnection instead of SqlDataSource. It doesn't depend on System.Web assembly (smaller deployment size for non-web situations), there's fewer layers in the stack trace (faster), and it's how most people are used to using ADO.NET.
var command = new OleDbCommand("UPDATE Users SET first_name = ? WHERE ID = ?");
command.Parameters.AddWithValue("id", Session["ColumnID"].ToString());
command.Parameters.AddWithValue("firstname", txt_firstname.Text);
using (var connection = new OleDbConnection(connectionString))
{
command.Connection = connection;
connection.Open();
command.ExecuteNonQuery();
}
Another note, you seem to be doing your database access directly in the UI layer! That's hard to test, and not very flexible. It'd be better if you moved all data access code into a separate class library, and then communicate back and forth by passing Models, which are code representations of database entities.
You're also using Access, which isn't really that great of a database system. MS SQL Server is much preferable.
That might look something like this:
Code Behind
DataLayer DB {get; set;}
protected void Page_Load(object sender, EventArgs e)
{
DB = new DataLayer("connectionstring");
}
protected void SubmitBtn_Click(object sender, EventArgs e)
{
SystemUser user = new SystemUser()
{
Id = Session["ColumnID"].ToString(),
FirstName = txt_firstname.Text
}
DB.UpdateUser(user);
}
Data Layer
public class DataLayer
{
string ConnectionString {get; set;}
public DataLayer(string connectionString)
{
ConnectionString = connectionString;
}
public void UpdateUser(SystemUser user)
{
var command = new SqlCommand("UPDATE Users SET first_name = #firstname WHERE ID = #id");
command.Parameters.AddWithValue("id", user.Id);
command.Parameters.AddWithValue("firstname", user.FirstName);
using (var connection = new SqlConnection(ConnectionString))
{
command.Connection = connection;
connection.Open();
command.ExecuteNonQuery();
}
}
public void ChangePassword(string UserId, string password)
{
//hash and change password here
}
}
Models
public class SystemUser
{
public string Id {get; set;}
public string FirstName {get; set;}
}

Categories