I'm writing Android application that connect with ASP.net web service (C#,3.5)
android Application send "Sign in" information of the user to web service to verify that if the user is registered or not.
here is the [WebMethod]
which receive the request :
[WebMethod]
public SigninPerson signin(SigninPerson SIPerson)
{
SigninPerson Temp = new SigninPerson(0, "", "", "", "");
LinqToSQLDataContext DataBase = new LinqToSQLDataContext();
var Person = (from a in DataBase.Persons
where a.Email == SIPerson.E_Mail &&
a.Password.Equals(SIPerson.Password,StringComparison.Ordinal)
select new SigninPerson
{
Person_Id = a.Person_Id,
F_Name = a.First_Name,
L_Name = a.Last_Name,
E_Mail = a.Email,
Password = a.Password
});
if (Person.Any() == true)
{
Temp = Person.FirstOrDefault();
}
return Temp;
}
SigninPerson
is a class which hold user information like First Name, Last Name , Password....
the problem is in the password comparison. it accepted all the cases
for example:
if the password for somebody which stored in DataBase is "ABD", and the user entered "abd" as password , the application accepted it! (not Case sensitive !!!)
how to solve this problem?
The C# Compare() method is used to compare first string with second string lexicographically. It returns an integer value. If both strings are equal, it returns 0. If first string is greater than second string, it returns 1 else it returns -1.
The Equals() method can be used to check if two strings are equal in C#. Two strings are considered equal if they have the same string values. The Equals() method returns True if the two strings are equal. Otherwise, it returns False .
You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not. On the other hand, equals() method compares whether the value of the strings is equal, and not the object itself.
We compare the strings by using the strcmp() function, i.e., strcmp(str1,str2). This function will compare both the strings str1 and str2. If the function returns 0 value means that both the strings are same, otherwise the strings are not equal.
Change your LINQ to this:
var Person = (from a in DataBase.Persons
where a.Email == SIPerson.E_Mail
select new SigninPerson
{
Person_Id = a.Person_Id,
F_Name = a.First_Name,
L_Name = a.Last_Name,
E_Mail = a.Email,
Password = a.Password
})
.ToList()
.Where(sp => sp.Password.Equals(SIPerson.Password));
This will force the string comparison to occur client-side, via the .NET framework, instead of server-side on the SQL Server.
As andleer stated, there is another approach that may be more efficient. Now, in practice it's unlikely you'd see this, but it's a good habit to get into. You could actually do this:
var Person = (from a in DataBase.Persons
where a.Email == SIPerson.E_Mail
select new SigninPerson
{
Person_Id = a.Person_Id,
F_Name = a.First_Name,
L_Name = a.Last_Name,
E_Mail = a.Email,
Password = a.Password
})
.Take(1)
.AsEnumerable()
.Where(sp => sp.Password.Equals(SIPerson.Password));
This should ensure that it would never return all the rows, but just 1. Again, in this actual case it's probably not that relevant because there would almost certainly only ever be one - but it's a nice thought to add and worth noting.
The problem is that SQL will not perform case sensitive matches unless it has been configured to do so, see here for more information.
Alternatively, you can just do the check via code after you have got your match:
Instead of if (Person.Any())
, use this:
var first = Person.FirstOrDefault();
if (first != null && first.Password == SIPerson.Password)
{
Temp = first;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With