I have a problem with WCF Service operation. I get passwod value from database and when it should pass it return false value. What am I doing wrong?
public bool LogIn(string userId, string passwd)
{
bool prompt;
ProgDBEntities context = new ProgDBEntities();
IQueryable<string> haslo = (from p in context.UserEntity where p.UserID == userId select p.Passwd);
bool passOk = String.Equals(haslo, passwd);
if (passOk == true )
{
prompt = true;
}
else
{
prompt = false;
}
return prompt;
}
It seems like you want to compare a single retrieved entry with the password that was passed in (as opposed to any IQueryable/IEnumerable). For that, try using the FirstOrDefault method:
public bool LogIn(string userId, string passwd)
{
bool prompt;
ProgDBEntities context = new ProgDBEntities();
var haslo = (from p in context.UserEntity where p.UserID == userId select p.Passwd).FirstOrDefault();
// No need to use String.Equals explicitly
bool passOk = haslo == passwd;
if (passOk == true )
{
prompt = true;
}
else
{
prompt = false;
}
return prompt;
}
haslo represents a collection of strings, not an individual string. This means String.Equals(haslo, passwd) will always return false since you're comparing a collection of strings to an individual string - they're two different types of objects.
You could try modifying the code as follows. FirstOrDefault() will return the first string in the collection, or NULL if it's empty.
bool passOk = String.Equals(haslo.FirstOrDefault(), passwd);
Related
I have this in my button click event:
protected void btn_login_Click(object sender, EventArgs e)
{
authentication auth = new authentication();
bool emailExists = auth.checkEmail(System.Convert.ToString(txt_email.Text));
if (emailExists == true)
{
btn_create.Text = "Email doesnt exist";
}
else
{
btn_create.Text = "Email exists";
}
}
It sends the email to my checkEmail method which is in my authentication class:
public bool checkEmail(string email)
{
bool emailExists = false;
usersTableAdapters.UsersTableAdapter user = new usersTableAdapters.UsersTableAdapter();
users.UsersDataTable userDataTable = user.checkEmail(email);
if (userDataTable.Rows.Count == 0)
{
emailExists = false;
}
else
{
emailExists = true;
}
return emailExists;
}
The checkEmail query is "SELECT COUNT(email) AS email FROM People WHERE (email = ?)"
However when I debug, it always falls through the if(emailExists == true) statement even when the email already exists in my DB, does anyone know why?
your query you entered will always have 1 result. If you want to continue using that query, you should check the first column ("email") of the first result and check to see if that is == 0 or not.
can't add code markup in comments, so reposting how I would rewrite the checkEmail method: (assuming the how the UsersTableAdapter type is setup)
public bool checkEmail(string email)
{
usersTableAdapters.UsersTableAdapter user = new usersTableAdapters.UsersTableAdapter();
users.UsersDataTable userDataTable = user.checkEmail(email);
return userDataTable.Rows[0][0] > 0;
}
I figured out I would have to check the index of the row which in this case is 0 and then retrieve and store the value from the email column into an int
DataRow row = userDataTable.Rows[0];
int rowValue = System.Convert.ToInt16(row["email"]);
I have to pass a count value to another namespace here. I have 2 classes Select.cs and Value.cs. Select.cs has the following code:
public bool Login(string UserName, string Password)
{
string strinvselect = string.Format("select * from newlog where
pass='{0}'", Password);
DataTable dtlog = ExecuteStatement(strinvselect);
if (dtlog.Rows.Count == 1)
{
string strvalue = string.Format("Select * FROM login WHERE uid=
'{0}'", UserName);
DataTable newlogin = ExecuteStatement(strvalue);
try
{
if (newlogin.Rows.Count == 1)
{
loginStatus = true;
}
}
catch (Exception ex)
{
loginStatus = false;
}
return loginStatus;
}
}
I have to create a count value if(newlogin.Rows.Count == 1), count=1 and this value should be available in Value.cs to check a functionality.
In Value.cs a function getdetails() is called. Here I need to check
if (count == 1)
{
getdetails();
}
else
{
// call another function
}
I found the answer:
Namespaces are not really relevant here, the issue is that you need to access the variable from a different class. The way you have "global" variables that are specific to the user is the Session, so store the value in a Session variable and have your other class access the Session variable.
HttpContext.Current.Session["myData"] = "somevalue";
Value function
string x;
if (Session["myData"] == null)
{
// handle the data not being set
}
else
{
x = (string)HttpContext.Current.Session["myData"].ToString(); ;
}
You can check for query for count outside Login ( basically wherever you need it ) then pass it as "username + count" (you will need to split it) to login first parameter as you can avoid checking count inside Login again.
I am trying to call the following get method in web api but I am currently experiencing an compiling error - 'bool' does not contain a definition for 'password' and no extension method 'password' accepting a first argument of type 'bool' could be found (are you missing a using directive or an assembly reference?) -- error
User class:
public class User : iUser
{
private cdwEntities db;
public User()
{
db = new cdwEntities();
}
public User(cdwEntities context)
{
db = context;
}
public bool Validate(string username, string password)
{
var query = from t in db.Trial_Try
join u in db.UserDetails on t.tUID equals u.uID
where t.tExpiryDate >= DateTime.Now &&
t.tPublication.Value == 163 &&
u.uUsername == username &&
u.uPassword == password
select u; //
// "execute" the query
return query.FirstOrDefault() != null;
}
Test class:
public HttpResponseMessage GetValidate(string username, string password)
{
User layer = new User();
var result = layer.Validate(username, password);
***if (result.username != null && result.password != null)***
{
var mes = string.Format("Success");
return Request.CreateErrorResponse(HttpStatusCode.NotFound, mes);
}
else
{
//var mis = string.Format("User {0} not found");
//return Request.CreateErrorResponse(HttpStatusCode.NotFound, mis, result);
return null;
}
}
Validate is returning a Boolean, not the result of the query. As #ekad stated, check result as a Boolean directly.
As an additional optimization, consider using .Any instead of FirstOrDefault since you don't need the hydrated result and can optimize the SQL to an Exists query rather than select top 1. Your validate method could then be:
public bool Validate(string username, string password)
{
var query = from t in db.Trial_Try
join u in db.UserDetails on t.tUID equals u.uID
where t.tExpiryDate >= DateTime.Now &&
t.tPublication.Value == 163 &&
u.uUsername == username &&
u.uPassword == password
select u; //
// "execute" the query
return query.Any();
}
The problem is result is a bool and it doesn't have username or password property, so you need to replace this line
if (result.username != null && result.password != null)
with this
if (result)
How do I get the Id in the login?
I'm using entity framework and in the frmLogin I have this:
private bool IsValidUser(string userName, string pass)
{
Context context = new Context();
var query = (from c in context.Cuentas
where c.Nombre == userName && c.Password == pass
select c);
return query.Any();
}
but with this function, I can only verify if the user is in the Database.
I want to get the id of this user too.
instead of the if(query.Any()) .... try:
var user = query.FirstOrDefault();
if (user == null)
return false;
var id = user.ID;
I think is possible to have only one user with th same username :) => one username = one user
you can try this
var user = context.Cuentas.singleordefault(d=>d.userName==userName & d.password==password);
int id;
if (user!=null)
{
id=user.userId;
return true;
}
return false;
EDITED
I get an error not all code paths return a value?
public string Authentication(string studentID, string password) // this line?
{
var result = students.FirstOrDefault(n => n.StudentID == studentID);
//find the StudentID that matches the string studentID
if (result != null)
//if result matches then do this
{
//----------------------------------------------------------------------------
byte[] passwordHash = Hash(password, result.Salt);
string HashedPassword = Convert.ToBase64String(passwordHash);
//----------------------------------------------------------------------------
// take the specific students salt and generate hash/salt for string password (same way student.Passowrd was created)
if (HashedPassword == result.Password)
//check if the HashedPassword (string password) matches the stored student.Password
{
return result.StudentID;
// if it does return the Students ID
}
}
else
//else return a message saying login failed
{
return "Login Failed";
}
}
if the result is not null but the result.Password != HashedPassword you're not returning anything.
You should change to something like:
...
if (HashedPassword == result.Password)
{
return result.StudentID;
// if it does return the Students ID
}
return "Invalid Password";
...
The problem is that your first if statement doesn't ensure the returning of a value, due to the nested if statement. Imagine you have result set to a value (not null) and your hashed password and supplied password do not match, if you follow that logic through you will fail to hit a return statement.
You should either add an else clause to your nested if statement like so:
if (HashedPassword == result.Password)
//check if the HashedPassword (string password) matches the stored student.Password
{
return result.StudentID;
// if it does return the Students ID
}
else
{
return "Login Failed";
}
or more desirably, remove the else statement you already have so the function ends with returning the login failed:
if (result != null)
{
//....
}
return "Login Failed";
...with this second approach you do no need to worry about using the else because if all your other conditions are satisfied, the nested return statement will end the function anyway. Try to think of this final return as the default action if any of the authentication steps fail
Another note to make on your code is that it is not ideal practise to be returning a mix of data in such a way. i.e. the result could be a student ID or it could be an error message. Consider creating a dedicated result class with multiple properties that the calling code can check to see the status of the logic validation. A class something like the following would be a good start:
public class LoginResult
{
//determines if the login was successful
public bool Success {get;set;}
//the ID of the student, perhaps an int datatype would be better?
public string StudentID {get;set;}
//the error message (provided the login failed)
public string ErrorMessage {get;set;}
}
(saying all that though, your calling code already appears to be aware of the studentID anyway)
remove the else. Just do
if(result != null) {
...
}
return "Login Failed";
you should also return something in case of:
if (HashedPassword != result.Password)
put an else in the inner if
i have made some changes in your code. try it.
public string Authentication(string studentID, string password)
{
var result = students.FirstOrDefault(n => n.StudentID == studentID);
var yourVar;
if (result != null)
{
byte[] passwordHash = Hash(password, result.Salt);
string HashedPassword = Convert.ToBase64String(passwordHash);
if (HashedPassword == result.Password)
{
//return result.StudentID;
yourVar = result.StudenID;
// if it does return the Students ID
}
}
else
//else return a message saying login failed
{
yourVar = "Login Failed";
}
return yourVar;
}