【问题标题】:ASP.NET MVC LinQ - Use our own method in "Any" LinQ expression?ASP.NET MVC LinQ - 在“任何”LinQ 表达式中使用我们自己的方法?
【发布时间】:2015-07-13 17:35:10
【问题描述】:

由于在网上找到了多篇文章,我在 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 无法识别方法 'Boolean VerifyHash(System.String, System.String, System.String)' 方法,并且此方法无法转换为存储表达式。

这是我的想法: 如果提供的密码(未加密)与存储在数据库中的加密密码匹配(通过获取与用户名对应的盐,在数据库中并用此盐重新加密提供的密码,然后将新加密的哈希与存储的一)。 用户名是唯一的。

我知道它不接受“任何”方法中的我的 VerifyHash 方法。但是我不知道该怎么做,因为除了匹配的用户名之外,我还需要相应的盐和加密密码(u.salt和u.password)来验证密码。

我尝试以相同的方式使用“查找”方法,但它不起作用(VS 错误,由于内存我需要用户 ID 将其作为参数传递)。我是 LinQ to Entities 的新手。

有什么想法吗?原谅我最终的英语错误。

谢谢,

地狱猫

【问题讨论】:

    标签: c# asp.net asp.net-mvc linq login


    【解决方案1】:

    您遇到了异常,因为实体框架无法将方法 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
        }
    }
    

    【讨论】:

    • 非常感谢! :) 最后似乎很容易,我几乎感到羞耻。一个问题:为什么您的变量是“var”而不是“用户”?我总是看到“var”而不是精确的类型。有什么原因吗?
    猜你喜欢
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多