string currentUser;
string currentPassword;
string getUserName;
string getPassword;
getUserName = Convert.ToString(Session["UserName"]);
getPassword = Convert.ToString(Session["Password"]);
currentUser = Convert.ToString(txtUserNameLogIn.Text);
currentPassword = Convert.ToString(txtPasswordLogin.Text);
if ((currentUser == getUserName ) && (currentPassword == getPassword)) {
currentUser = Convert.ToString(Session["CurrentUser"]);
currentPassword = Convert.ToString(Session["CurrentPassword"]);
Response.Redirect("Home.aspx");
} else {
lblResult.Text = "Invalid Password";
}
I have 3 pages. First one for registration, that saves UserName and Password so a Session and then I have login page that should take the UserName and Password sessions and compare them to the current user input on this page. So far I'm not getting any responses.
Edit: The username and password that I put in on previous page gets stored in a Session Variable called "UserName", the person gets re-directed to login page and I simply want to compare what user types in with the Session Variable from previous page and if it's correct, store that information in new Session Variable and re-direct user to home page.
You can do several things here working under the assumption this is a test project and you know Session is not the correct place to store plaintext credentials. Take a look at SimpleMembership for a cleaner approach.
That out of the way I created two extension classes. The first takes care of string security, and the second takes care of Session. You can take this a step further and create constants for the keys or even a SessionUser object. In terms of comparison I just combined both username+password so the logic is short.
public static class StringExtensions
{
public static string Encrypt(this string plainText)
{
// Replace with your encryption impl
return plainText;
}
public static string Decrypt(this string hiddenText)
{
// Replace with your decryption impl
return hiddenText;
}
}
public static class SessionExtensions
{
public static void Set<T>(this HttpSessionState sessionState, string key, T value)
{
sessionState[key] = value;
}
public static T Get<T>(this HttpSessionState sessionState, string key) where T : class
{
return (T)sessionState[key];
}
}
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
Session.Set("UserName", "something");
Session.Set("Password", "something".Encrypt());
var username = Session.Get<string>("UserName");
var password = Session.Get<string>("Password").Decrypt();
var savedUser = $"{username}{password}";
var currentUser = $"somethingsomething";
if (currentUser.Equals(savedUser, StringComparison.InvariantCultureIgnoreCase))
{
}
else
{
}
}
}
Related
I'm trying to create a class called User that can register new Users and store them in a list. Currently, I just want to be able to use the RegisterUser object. I have a C# book and have tried understanding it, but it's not clicking. Any help or hints in the right direction are very much appreciated.
namespace UserClass {
/// <summary>
/// The user class
/// <summary>
public class User {
public string userName;
public string password;
public string address;
public int contactNumber;
public static RegisterUser(string username, string pass, string add, int contact) {
User newUser = new User();
newUser.userName = username;
newUser.password = pass;
newUser.address = add;
newUser.contactNumber = contact;
WriteLine(newUser);
};
}
}
A few issues with your code:
WriteLine is incorrect unless you've created that method
I think you're looking for Console.WriteLine(...) which you can
use after adding using System; however even that would be
incorrect.
I assume you are looking to print the values of fields in
the User class which in that case, either override .ToString
(bad idea) or access and print them separately.
RegisterUser has no return type
It could be void -> public static void RegisterUser(string username, string pass, string add, int contact) indicating that nothing is returned.
However, common convention and expectation would be that the new User object is returned so that the caller can know what the final state of the operation was ->
You have a rogue ; at the end of the implementation of RegisterUser(...)
You need to remove it to make your code compile.
You actually have no variables anywhere, which would allow you to create a collection
You need to add your users to something like a List<User>, which would be encapsulated internally in another class perhaps called UserManager. This allows you to expose behaviour but hide the implementation, as well as adhering to SRP.
You could then expose the collection of users if you needed to, in a clear way, using a ReadOnlyCollection<User>.
This would show consumers that they would probably have to call a method (RegisterUser) to be able to add to the collection of users as ReadOnlyCollection<User> prevents modification, and not just do users.Add(...) & bypass your registration logic.
In this case, RegisterUser would also not have the static keyword, as it would need access to the instance field - your collection of users - and it won't be able to do that as a static method.
Your namespace is extremely specific to your User class
It's technically okay but namespaces are used to organise classes & control scope. I would rename it to something more related to your domain, as opposed to something bound to your class name (UserClass).
Arguments for RegisterUser
I would also cut down on the number of arguments to RegisterUser, take in a User object and then enforce all fields being set using the constructor for User.
This would turn it into a monadic method, making the code more readable, easier to test later on and makes you keep a conscious tab on how many "things" the method is responsible for.
Something like the below should work:
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace MyApplication
{
public class User
{
public string UserName;
public string Password;
public string Address;
public int ContactNumber;
public User(string username, string pass, string add, int contact)
{
UserName = username;
Password = pass;
Address = add;
ContactNumber = contact;
}
}
public class UserManager
{
private readonly List<User> _users = new List<User>();
public ReadOnlyCollection<User> GetUsers()
{
return _users.AsReadOnly();
}
public User RegisterUser(User newUser)
{
// process user, modify fields, add etc.
_users.Add(newUser);
return newUser;
}
}
public static class UserOutput
{
public static void WriteUserToConsole(User user)
{
Console.WriteLine($"{user.UserName}, {user.Password}, {user.Address}, {user.ContactNumber}");
}
}
}
var userManager = new UserManager();
var userToBeRegistered = new User("A", "B", "C", 0);
var createdUser = userManager.RegisterUser(userToBeRegistered);
UserOutput.WriteUserToConsole(createdUser);
var allUsers = userManager.GetUsers();
foreach (var user in allUsers)
UserOutput.WriteUserToConsole(user);
you are nearly there
public class User
{
public string userName;
public string password;
public string address;
public int contactNumber;
}
// Separate Class to create and store the users
public class UserController
{
// List to store your Users
public List<User> UserList;
// Constuctor instatiates UserList
public UserController()
{
UserList = new List<User>();
}
public void RegisterUser(string username, string pass, string add, int contact) {
User newUser = new User();
newUser.userName = username;
newUser.password = pass;
newUser.address = add;
newUser.contactNumber = contact;
// Adding the user to the UserList
UserList.Add(newUser);
// Show the userName of the new User in Console
Console.WriteLine(newUser.userName);
}
}
you can now Register users with your method in the new separate class. They will be stored in the UserList that you can access freely from outside of the class.
usage:
//get a UserController to start working
UserController controller = new UserController();
// call to RegisterUser
controller.RegisterUser("bob", "1234", "mystreet 1", 42);
I feel like you are close. See if the following points will help.
RegisterUser is a function/method with no purpose as it is missing a return type specification. Here you have two design options:
Create a new user and return a variable referencing this user.
static User RegisterUser( ... )
{
newUser = new User();
...
return newUser;
}
Create a new user and store the user internally to a list. This means the function specification must have void in its return type.
static List<User> userList = new List<User>();
static void RegisterUser( ... )
{
newUser = new User();
...
userList.Add(newUser);
}
You can specify the required information to define a user by declaring a constructor which assigns this information when a new User object is created. For example, if the username and password are the only required field then
Create a constructor accepting these two values
public class User
{
...
public User(string userName, string password)
{
this.userName = userName;
this.password = password;
}
}
Change the fields on readonly such that they cannot be modified at a later time.
public class User
{
public readonly string userName;
public readonly string password;
public string address;
public int contactNumber;
...
}
There is no defined way to display the information for each user on the console and so a call to Console.WriteLine(user) will only display the user type (default behavior of C#). To add this functionality to a class, override the ToString() method.
public class User
{
...
public override string ToString()
{
return $"User = {userName}, Address = {address}, Contact = {contactNumber}";
}
}
Now in the main program when you loop through the registered users, you can simply invoke Console.WriteLine() on each one to show on the screen the information.
static void Main(string[] args)
{
User.RegisterUser("aaa", "abc1", "100 east", 55500);
User.RegisterUser("xyz", "uvw5", "120 north", 55501);
foreach (var user in User.registededUsers)
{
Console.WriteLine(user);
}
}
it is common practice to hide fields behind properties. In this case it would be useful not to expose the list of registered users outside of the class as List<User> because it will allow the addition of new items in the list without requiring to call the RegisterUser() function. To disallow this behavior remove the public from the registededUsers field and add a property called RegisteredUsers expose this field as a IReadOnlyList<User>
public class User
{
...
static List<User> registededUsers = new List<User>();
public static IReadOnlyList<User> RegisteredUsers { get => registededUsers.AsReadOnly(); }
}
public async Task<IActionResult> Register(RegisterUserVM userVM)
{
if(!ModelState.IsValid) return View();
AppUser user = new AppUser
{
Name = userVM.Name,
Email = userVM.Email,
Surname = userVM.Surname,
UserName = userVM.Username
};
var result = await _userManager.CreateAsync(user,userVM.Password);
if (!result.Succeeded)
{
foreach (var item in result.Errors)
{
ModelState.AddModelError("", "ur username or password invalid");
return View();
}
}
return RedirectToAction("Index", "Home");
}
enter code here
public async Task<IActionResult> Login(LoginUserVM userVM)
{
if(!ModelState.IsValid) return View();
var user = await _userManager.FindByNameAsync(userVM.UsernameorEmail);
if(user == null)
{
user = await _userManager.FindByEmailAsync(userVM.UsernameorEmail);
if (user == null)
{
ModelState.AddModelError("", "ur username or password invalid");
return View();
}
}
var result = await _signInManager.PasswordSignInAsync(user, userVM.Password, userVM.IsPersistance, true);
if (!result.Succeeded)
{
ModelState.AddModelError("", "ur username or password invalid");
return View();
}
return RedirectToAction("Index","Home");
}
I created a class User, which contain simple variables as shown below:
public class User
{
public string username; //Unique usernames
public string password;
}
I then instantiate a list of an object in another class:
List<User> user = new List<User>();
user.Add(new User {username = "admin", password = "123"});
How is it possible for me to retrieve the password's value by searching for the username using a foreach loop? I am probably just confused but this is what I came up with:
foreach(var item in user)
{
if(item.Equals(username_input))
{
//I try to store the password into a string pass_check
pass_check = item.password;
}
}
if (user_input.Equals(pass_check))
{
Console.WriteLine("Login successful");
}
Sorry if this seems like a dense question to anyone out there, still a beginner trying to learn!
You're pretty close..
if(item.username.Equals(username_input))
You need to check the property of the item in this case which is username.
You could even shorten it to:
foreach(var item in user)
{
if(item.username.Equals(username_input)
&& user_input.Equals(item.password))
{
Console.WriteLine("Login successful");
break; // no need to check more.. or is there?
}
}
You can get really fancy using Linq:
if (user.Any(i => i.username.Equals(username_input)
&& user_input.Equals(i.password))
{
Console.WriteLine("Login successful");
}
As juharr noted in the commend, best practices for exposing values from class/objects is to use Properties not Fields..
public class User
{
// not best practices
public string username;
// best practices
public string password { get; set; }
}
Even fancier:
using System.Linq;
public static class Extensions
{
// Extension method that works on List<User> to validate user && PW
// - returns true if user exists and pw is ok, else false
public static bool CheckUserPassword(this List<User> users, string user_name, string pw)
{
// add null checks for users, user_name and pw if you are paranoid of know your customers ;o)
return users.Any(u => u.username == user_name && u.password == pw);
}
}
public class User
{
public string password;
public string username; //Unique usernames
}
internal class Program
{
private static List<User> users = new List<User> { new User { username = "admin", password = "123" } };
static void Main(string[] args)
{
// use extension method like this:
var isValid = users.CheckUserPassword("Hello","Jeha");
Console.WriteLine($"user 'admin' with pw '8888' => {users.CheckUserPassword("admin", "8888")}");
Console.WriteLine($"user 'admin' with pw '123' => {users.CheckUserPassword("admin", "123")}");
Console.ReadLine();
}
}
Extension Methods can be executed on the this-part - in this case only on List<User>s. The Extensionmethod uses Linq to find if Any (at least 1) user of this name and pw exists.
I am new to C# and I am working on a project for my studies and I have multiple logins an Administrator and Teacher. This project has multiple winforms the 2 I am needing help with is my Login and the Main form after the user logs in.
I have already created the logins and they work but I need to disable a button called btnMarks int he Main form the Administrator cannot have access to this button.
I have tried if statements but I can't seem to make it work. I am using radio buttons for logins as well as the Administrator and Teachers logins have their own tables in the database. I can only use Entities not SQLconnections it is part of the project for my studies.
Please help
Below is my user login form code.
private void btnLogin_Click(object sender, EventArgs e)
{
//A check to make sure both fields have an entry
if(txtUsername.Text == "" || txtPassword.Text == "")
{
MessageBox.Show("Please provide a Username and Password!");
return;
}
//This is to call the boolean radiobuttons are checked
radioButtons();
//Teachers login
if (rbTeachers.Checked)
{
int Username = Convert.ToInt32(txtUsername.Text);
SchoolDBEntities db = new SchoolDBEntities();
var tid = from t in db.Teachers
where t.TID == Username
&& t.Password == txtPassword.Text
select t;
if (tid.Any())
{
MessageBox.Show("You are now logged in as a Teacher!");
this.Hide();
Main tss = new Main();
tss.Show();
}
else
{
MessageBox.Show("Incorrect Username or Password!");
}
}
//Administrator login
if (rbAdmin.Checked)
{
int Username = Convert.ToInt32(txtUsername.Text);
SchoolDBEntities db = new SchoolDBEntities();
var aid = from a in db.Administrators
where a.AID == Username
&& a.Password == txtPassword.Text
select a;
if (aid.Any())
{
MessageBox.Show("You are now logged in as Administrator");
this.Hide();
Main tss = new Main();
tss.Show();
}
else
{
MessageBox.Show("Incorrect Username or Password");
}
}
}
Below is my Main form, I need the btnMarks button disabled for Administrators.
I am unsure where to put the code to disable this button as well. If I could be able to call the radio button from the login form please show me how.
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
private void Main_Load(object sender, EventArgs e)
{
}
private void btnMarks_Click(object sender, EventArgs e)
{
frmStudentMarks marks = new frmStudentMarks();
marks.ShowDialog();
}
Thanks
I would recommend you making something like SessionManagement object to manage current session ( logged user, user rights etc. ).
public static class SessionManagement
{
static UserEntity sessionUser = null;
public static void LoggedAs(UserEntity user)
{
sessionUser = user;
}
// other methods/fields to manage session
}
After doing this you can just set session for currently logged user :
var tid = from t in db.Teachers
where t.TID == Username
&& t.Password == txtPassword.Text
select t;
SessionManagement.LoggedAs((UserEntity)tid); // make some explicit operators or something.
Now you have full control over who is logged in and you can check it's rights so all you have to do is to check it after InitializeComponent() method call :
public Main()
{
InitializeComponent();
btnMarks.Enabled = !SessionManagement.CurrentUser.IsAdministrator;
}
EDIT:
You've asked if there's something else you should do for this code to make it works. Answer is yes. This answer is basically a scheme for you to work something out. But since it's not an easy thing to do I'll explain it in somewhat more details.
Firstly, you have 2 types of Entity: Teacher and Administrator and you need to make one "unified" entity ( I named it UserEntity ). This unified entity should be convertible from both Teacher and Administrator entity.
My recommendation in code :
public class UserEntity
{
string _username;
public string Username
{
get { return _username; }
}
bool _isAdministrator;
public bool IsAdministrator
{
get { return _isAdministrator; }
}
public UserEntity(Administrator entity)
{
_isAdministrator = true;
_username = entity.AID;
}
public UserEntity(Teacher entity)
{
_isAdministrator = false;
_username = entity.TID;
}
public static explicit operator UserEntity(Administrator entity)
{
return new UserEntity(entity);
}
public static explicit operator UserEntity(Teacher entity)
{
return new UserEntity(entity);
}
}
Now you can do somehting like UserEntity userEntity = (UserEntity)teacher;
Next thing to do is to update SessionManagement by adding new method into it :
public static void LoggedAs(UserEntity entity)
{
if(sessionUser != null)
throw new InvalidOperationException("Cannot be logged 2 times with the same session");
sessionUser = entity;
}
And a property :
public static UserEntity CurrentUser
{
get { return sessionUser; }
}
Now all you have to do is to combine all of these into one huge chunk of code :
private void btnLogin_Click(object sender, EventArgs e)
// parts of your code till this line :
SchoolDBEntities db = new SchoolDBEntities();
var tid = from t in db.Teachers
where t.TID == Username
&& t.Password == txtPassword.Text
select t;
Teacher teacher = tid.FirstOrDefault();
if(teacher != null)
{
SessionManagement.LoggedAs((UserEntity)teacher);
}
// do the same with Administrator
Now since SessionManagement is static object you can use it everywhere inside your application and it will persist with all stored data meaning you can use :
public Main()
{
InitializeComponent();
btnMarks.Enabled = !SessionManagement.CurrentUser.IsAdministrator;
}
You need to maintain a static class for that in which you can add that the current user's type.
Kindly go through the following url
https://stackoverflow.com/a/14599474/1526972
The command button, by default, has a public access level so you can access and disable it from login form before to call the Show() method in this way:
tss.yourButtonName.Enabled = false;
Hope this help.
Christian
So I have a simple User Class:
public class User
{
public string id, name, email, image;
public User (IFBGraphUser user)
{
id = user.GetId ();
name = user.GetName ();
GetEmail ();
}
private void GetEmail()
{
FBRequestConnection.StartWithGraphPath("/me", null, "GET", delegate(FBRequestConnection connection, NSObject result, NSError error) {
var me = (FBGraphObject)result;
this.email = me["email"].ToString();
});
}
}
But I need to get the users email from Facebook. My Facebook request has a delegate and when I try to assign the email field inside the delegate, the email field remains null. How can I go about getting the email into the email field from the delegate?
Its not a problem with the facebook result, ive tried this.email = "test"; and it was still null when I went to access it.
In this Code i am setting a class level field's value and accessing it outside of delegate so this might help you, see the below given code:-
public delegate void delgJournalBaseModified(string a);
public class User
{
public string id, name, email, image;
public User(string uid,string uName)
{
id = uid;
name = uName;
Console.WriteLine(this.name);
Console.WriteLine(this.email);
GetEmail();
}
private void GetEmail()
{
set(delegate(string d)
{
this.email = d;
});
}
private void set(delgJournalBaseModified delgJournalBaseModified)
{
delgJournalBaseModified.Invoke("value is set");
Console.WriteLine(this.email);
}
}
and call like this in main method or anywhere you like..
User a1 = new User("123", "dev");
Console.WriteLine(a1.email);
now if you will the console "value is set" is being print twice.
Thanks
Devendra
I need a Login function(login is just an example, any other frequently used method can be fine) which takes email and password as parameter and asks DB if there is such a user. If yes, it has to return customer_id(int), if no, it will return the message why login could not happen(ex:no such an email address).
I also do not wanna rewrite the login function everytime. I want to write it once in a common project which I can use in my every project and reuse it. But i am trying to find out the best practice for this. So far, i thought something like below, but the problem for me is that i cannot return customerID which i will get in codebehind in my projects(any other project) and open a session variable with it. I only can return strings in below structure. I also thought returning a Dic, but this also is wrong I guess because if bool(key) happens to be true, customerID is not a string(value). Can you help me please learning the correct way of using common functions with no need to think the returning messages and variables twice? Thanks a lot
public class UserFunctions
{
private enum Info
{
//thought of returning codes??
LoginSuccess = 401,
NoMatchPasswordEmail = 402,
InvalidEmail = 403,
};
public string TryLogin(string email, string password)
{
bool isValidEmail = Validation.ValidEmail(email);
if (isValidEmail == false)
{
return Result(Info.InvalidEmail);
// returning a message here
}
Customers customer = new Customers();
customer.email = email;
customer.password = password;
DataTable dtCustomer = customer.SelectExisting();
if (dtCustomer.Rows.Count > 0)
{
int customerID = int.Parse(dtCustomer.Rows[0]["CustomerID"].ToString());
return Result(Info.LoginSuccess);
// Here I cant return the customerID. I dont wanna open a session here because this function has no such a job. Its other projects button events job I guess
}
else
{
return Result(Info.NoMatchPasswordEmail);
}
}
private string Result(Info input)
{
switch (input)
{
case Info.NoMatchPasswordEmail:
return "Email ve şifre bilgisi uyuşmamaktadır";
case Info.InvalidEmail:
return "Geçerli bir email adresi girmelisiniz";
case Info.LoginSuccess:
return "Başarılı Login";
}
return "";
}
}
You may want to consider returning an instance of a custom class.
public class LoginResult
{
public Info Result { get; set; }
public int CustomerId { get; set;}
}
Modify your TryLogin method to return an instance of LoginResult.
Base your application flow on the result:
var loginResult = TryLogin(..., ...);
switch (loginResult.Result)
{
case Info.LoginSuccess:
var customerId = loginResult.CustomerId;
//do your duty
break;
case Info.NoMatchPasswordEmail:
//Yell at them
break;
...
}
You could try Creating an event and then the calling code can register to the event before attempting to login.
For example:
public class UserFunctions
{
private enum Info
{
LoginSuccess = 401,
NoMatchPasswordEmail = 402,
InvalidEmail = 403,
};
public delegate void LoginAttemptArgs(object sender, Info result, int CustomerID);//Define the delegate paramters to pass to the objects registered to the event.
public event LoginAttemptArgs LoginAttempt;//The event name and what delegate to use.
public void TryLogin(string email, string password)
{
bool isValidEmail = Validation.ValidEmail(email);
if (isValidEmail == false)
{
OnLoginAttempt(Info.InvalidEmail, -1);
}
Customers customer = new Customers();
customer.email = email;
customer.password = password;
DataTable dtCustomer = customer.SelectExisting();
if (dtCustomer.Rows.Count > 0)
{
int customerID = int.Parse(dtCustomer.Rows[0]["CustomerID"].ToString());
OnLoginAttempt(Info.LoginSuccess, customerID);
}
else
{
OnLoginAttempt(Info.NoMatchPasswordEmail, -1);
}
}
private void OnLoginAttempt(Info info, int CustomerID)
{
if (LoginAttempt != null)//If something has registered to this event
LoginAttempt(this, info, CustomerID);
}
}
I wouldn't compile a string to return, I would return the enum result and let the calling code do what it likes with the result. reading an enum is much quicker than parsing returned string.
Edit: Typos and i missed an event call... .Twice