You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVC重置密码功能无法更新SSMS数据库问题求助

MVC重置密码功能数据库不更新问题排查与修复

我正在MVC框架中开发忘记密码与重置密码功能,已经实现了密码匹配校验、非空校验、用户存在性校验等逻辑,但用户通过邮件链接输入新密码后,SSMS数据库里的密码始终没更新。试了各种方法查资料都没找到原因,相关代码如下:


原代码展示

HomeController.cs

[HttpGet]
public ActionResult ResetPassword()
{
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ResetPassword(UserLogin user)
{
    if (ModelState.IsValid) {
        var users = db.UserLogins.Where(a => a.ConfirmPassword.Equals(user.Password)).FirstOrDefault();
        if (user != null)
        {
            db.UserLogins.Remove(users);
            var newPassword = user.Password;
            newPassword = encryptPassword(users.Password);
            db.Configuration.ValidateOnSaveEnabled = false;
            db.SaveChanges();
            ViewBag.Message = "Password updated successfully, you may return to homepage";
            RedirectToAction("Login");
        }
        else
        {
            ViewBag.Message = "Something went wrong";
        }
    }
    return View();
}

ResetPassword.cshtml

@model ProductionDashboardApp.Models.UserLogin

@{
    ViewBag.Title = "ResetPassword";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<body style="text-align:center">
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
        <div class="login-page">
            <div class="form">
                <form class="login-form">
                    <div class="editor-label">
                        @Html.LabelFor(model => model.Password, "Contraseña")
                    </div>
                    <div class="editor-field">
                        @Html.PasswordFor(model => model.ConfirmPassword)
                        @Html.ValidationMessageFor(model => model.Password)
                    </div><div class="editor-label">
                        @Html.LabelFor(model => model.ConfirmPassword, "Confirmar contraseña")
                    </div>
                    <div class="editor-field">
                        @Html.PasswordFor(model => model.ConfirmPassword)
                        @Html.ValidationMessageFor(model => model.ConfirmPassword)
                    </div>
                    <input type="submit" value="RESET" />
                </form>
            </div>
        </div>
    }
</body>

UserLogin.cs

namespace ProductionDashboardApp.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public partial class UserLogin
    {
        [Required(ErrorMessage = "Please, provide your Employee ID", AllowEmptyStrings = false)]
        public int UserID { get; set; }
        [Required(ErrorMessage = "Please, provide your first name", AllowEmptyStrings = false)]
        public string FirstName { get; set; }
        [Required(ErrorMessage = "Please, provide your last name", AllowEmptyStrings = false)]
        public string LastName { get; set; }
        [Required(ErrorMessage = "Please, provide an username", AllowEmptyStrings = false)]
        public string Username { get; set; }

        [Required(ErrorMessage = "Please, provide a password", AllowEmptyStrings = false)]
        [DataType(DataType.Password)]
        public string Password { get; set; }
        [DataType(DataType.Password)]
        [Compare("Password", ErrorMessage = "Passwords do not match")]
        public string ConfirmPassword { get; set; }

        [Required(ErrorMessage = "Please, provide your email", AllowEmptyStrings = false)]
        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }
    }
}

问题根源及修复方案

1. 用户定位逻辑完全错误

原代码用a.ConfirmPassword.Equals(user.Password)查询用户,但ConfirmPassword是前端校验字段,数据库不会存储该值;且重置密码必须通过邮件链接携带的**用户唯一标识(如UserID/Email)**定位目标用户,而非用新密码匹配不存在的字段。

2. 密码更新逻辑混乱

  • 错误执行了用户删除操作db.UserLogins.Remove(users),重置密码是更新而非删除
  • 加密时使用了旧密码encryptPassword(users.Password),而非用户输入的新密码
  • 未将加密后的新密码赋值给用户对象的Password属性,数据库无更新依据

3. 嵌套表单导致提交失效

视图中@using (Html.BeginForm())已生成表单,内部又嵌套<form class="login-form">,嵌套表单会导致提交行为异常,后端无法接收正确参数。

4. 跳转逻辑未生效

调用RedirectToAction("Login")但未加return,页面不会跳转,且应在保存成功后执行跳转。


修复后的代码

HomeController.cs(修正版)

[HttpGet]
// 邮件链接需携带用户唯一标识,示例用UserID
public ActionResult ResetPassword(int userId)
{
    // 校验重置链接有效性
    var targetUser = db.UserLogins.FirstOrDefault(u => u.UserID == userId);
    if (targetUser == null)
    {
        ViewBag.Message = "无效的密码重置链接";
        return View();
    }
    ViewBag.TargetUserId = userId;
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ResetPassword(int targetUserId, UserLogin model)
{
    if (ModelState.IsValid)
    {
        var targetUser = db.UserLogins.FirstOrDefault(u => u.UserID == targetUserId);
        if (targetUser != null)
        {
            // 加密用户输入的新密码并赋值
            targetUser.Password = encryptPassword(model.Password);
            db.Configuration.ValidateOnSaveEnabled = false;
            db.SaveChanges();
            ViewBag.Message = "密码更新成功,即将跳转至登录页";
            return RedirectToAction("Login");
        }
        ViewBag.Message = "用户不存在,操作失败";
    }
    ViewBag.TargetUserId = targetUserId;
    return View(model);
}

ResetPassword.cshtml(修正版)

@model ProductionDashboardApp.Models.UserLogin

@{
    ViewBag.Title = "重置密码";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<body style="text-align:center">
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
        <!-- 隐藏域携带目标用户ID,用于后端定位 -->
        @Html.Hidden("targetUserId", ViewBag.TargetUserId)
        
        <div class="login-page">
            <div class="form">
                <!-- 移除嵌套的form标签 -->
                <div class="login-form">
                    <div class="editor-label">
                        @Html.LabelFor(model => model.Password, "新密码")
                    </div>
                    <div class="editor-field">
                        @Html.PasswordFor(model => model.Password)
                        @Html.ValidationMessageFor(model => model.Password)
                    </div>
                    <div class="editor-label">
                        @Html.LabelFor(model => model.ConfirmPassword, "确认新密码")
                    </div>
                    <div class="editor-field">
                        @Html.PasswordFor(model => model.ConfirmPassword)
                        @Html.ValidationMessageFor(model => model.ConfirmPassword)
                    </div>
                    <input type="submit" value="重置密码" />
                </div>
            </div>
        </div>
    }

    @if (!string.IsNullOrEmpty(ViewBag.Message))
    {
        <p style="margin-top:20px;">@ViewBag.Message</p>
    }
</body>

补充说明

  • 邮件发送的重置链接需包含用户唯一标识,示例格式:/Home/ResetPassword?userId=123
  • 确保encryptPassword方法的加密逻辑与登录时的密码验证逻辑完全一致
  • 可额外添加密码强度校验(如长度、字符类型要求)提升账号安全性

内容的提问来源于stack exchange,提问作者Naksu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 11:57:45