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
    }
}