我正在编写与ASP.net Web服务(C#,3.5)连接的Android应用程序
android应用程序向Web服务发送“登录”用户信息,以验证用户是否已注册。
这是接收请求的[WebMethod]
:
[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
是一个保存用户信息的类,如名字,姓氏,密码......
问题在于密码比较。它接受了所有案件
例如:
如果存储在DataBase中的某人的密码是“ABD”,并且用户输入了“abd” 作为密码,应用程序接受了它! (不区分大小写!)
如何解决这个问题?
答案 0 :(得分:4)
将LINQ更改为:
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));
这将强制字符串比较通过.NET框架发生在客户端,而不是SQL Server上的服务器端。
正如andleer所说,还有另一种方法可能更有效。现在,在实践中,你不太可能看到这一点,但这是一个很好的习惯。你实际上可以这样做:
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));
这个应该确保它永远不会返回所有行,而只是1.再次,在这个实际情况下它可能不那么相关,因为几乎肯定只有一个 - 但它是一个很好的想法添加并值得注意。
答案 1 :(得分:1)
问题是SQL不会执行区分大小写的匹配,除非它已配置为执行此操作,see here for more information。
或者,您可以在获得匹配后通过代码进行检查:
而不是if (Person.Any())
,请使用:
var first = Person.FirstOrDefault();
if (first != null && first.Password == SIPerson.Password)
{
Temp = first;
}