ASP.NET MVC LinQ - 在 "Any" LinQ 表达式中使用我们自己的方法?
ASP.NET MVC LinQ - Use our own method in "Any" LinQ expression?
我在 asp.net mvc 中编写了一个登录页面,这要归功于在网上找到的多篇文章,但我在数据库中找到匹配的用户时遇到了问题。
这是我的 POST 方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login([Bind(Include = "username, password")] user model, string returnUrl)
{
if (ModelState.IsValid)
{
string username = model.username.ToLower();
string plainPassword = model.password;
bool userValid = db.user.Any(u => SHA512.VerifyHash(plainPassword, u.salt, u.password) && u.username_canonical == username);
if (userValid)
{
FormsAuthentication.SetAuthCookie(username, false);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The username or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
我在这一行得到了一个 "NotSupportedException" :
bool userValid = db.user.Any(u => SHA512.VerifyHash(plainPassword, u.salt, u.password) && u.username_canonical == username);
LINQ to Entities does not recognize the method 'Boolean VerifyHash(System.String, System.String, System.String)' method, and this method cannot be translated into a store expression.
这是我的想法:
VerifyHash returns 如果提供的密码(未加密)与存储在数据库中的加密密码匹配(通过获取与用户名对应的盐,在数据库中并用该盐重新加密提供的密码,然后比较新加密的密码,则为真与存储的散列)。
用户名是唯一的。
我知道它不接受我在 "Any" 中的 VerifyHash 方法。但我不知道该怎么做,因为除了匹配的用户名来验证密码外,我还需要相应的盐和加密密码(u.salt和u.password)。
我尝试以相同的方式使用 "Find" 方法,但它不起作用(VS 错误,根据记忆,我需要用户 ID 将其作为参数传递)。我是 LinQ to Entities 的新手。
有什么想法吗?请原谅我最终的英语错误。
谢谢,
地狱猫
您收到异常,因为 entity framework 无法将方法 VerifyHash
转换为 SQL 语法。 VerifyHash
是用C#实现的,在SQL中没有对应的方法。
为什么不先按用户名搜索用户,然后再验证密码。你可以这样做:
var userFromDB = db.user.FirstOrDefault(u => u.username_canonical == username);
if(userFromDB !=null)
{
var userValid = SHA512.VerifyHash(plainPassword, userFromDB.salt, userFromDB.password)
if (userValid)
{
// your logic
}
}
我在 asp.net mvc 中编写了一个登录页面,这要归功于在网上找到的多篇文章,但我在数据库中找到匹配的用户时遇到了问题。 这是我的 POST 方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login([Bind(Include = "username, password")] user model, string returnUrl)
{
if (ModelState.IsValid)
{
string username = model.username.ToLower();
string plainPassword = model.password;
bool userValid = db.user.Any(u => SHA512.VerifyHash(plainPassword, u.salt, u.password) && u.username_canonical == username);
if (userValid)
{
FormsAuthentication.SetAuthCookie(username, false);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The username or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
我在这一行得到了一个 "NotSupportedException" :
bool userValid = db.user.Any(u => SHA512.VerifyHash(plainPassword, u.salt, u.password) && u.username_canonical == username);
LINQ to Entities does not recognize the method 'Boolean VerifyHash(System.String, System.String, System.String)' method, and this method cannot be translated into a store expression.
这是我的想法: VerifyHash returns 如果提供的密码(未加密)与存储在数据库中的加密密码匹配(通过获取与用户名对应的盐,在数据库中并用该盐重新加密提供的密码,然后比较新加密的密码,则为真与存储的散列)。 用户名是唯一的。
我知道它不接受我在 "Any" 中的 VerifyHash 方法。但我不知道该怎么做,因为除了匹配的用户名来验证密码外,我还需要相应的盐和加密密码(u.salt和u.password)。
我尝试以相同的方式使用 "Find" 方法,但它不起作用(VS 错误,根据记忆,我需要用户 ID 将其作为参数传递)。我是 LinQ to Entities 的新手。
有什么想法吗?请原谅我最终的英语错误。
谢谢,
地狱猫
您收到异常,因为 entity framework 无法将方法 VerifyHash
转换为 SQL 语法。 VerifyHash
是用C#实现的,在SQL中没有对应的方法。
为什么不先按用户名搜索用户,然后再验证密码。你可以这样做:
var userFromDB = db.user.FirstOrDefault(u => u.username_canonical == username);
if(userFromDB !=null)
{
var userValid = SHA512.VerifyHash(plainPassword, userFromDB.salt, userFromDB.password)
if (userValid)
{
// your logic
}
}