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
相关产品推荐
相关产品推荐

