.NET MVC6中Post请求时Token变为Null的问题求助
重置密码提交后ResetCode变为Null的问题
我有一个[HttpGet]方法,接收token并将其存储到ResetPassword表的ResetCode列中。[HttpGet]方法中模型获取token值正常,但输入密码提交后,token变为Null。注:我是Asp.net新手。
相关代码
HttpGet 方法
[HttpGet] public ActionResult ResetPassword(string id) { using (CiPlatformDbContext db = new CiPlatformDbContext()) { var user = db.Users.Where(a => a.ResetPasswordCode == id).FirstOrDefault(); if (user != null) { ResetPasswordVM vm = new ResetPasswordVM(); vm.ResetCode = id; return View(vm); } else { return RedirectToAction("Login", "Home"); } } }
HttpPost 方法
[HttpPost] [AutoValidateAntiforgeryToken] public IActionResult ResetPassword(ResetPasswordVM obj) { if (ModelState.IsValid) { using (CiPlatformDbContext db = new CiPlatformDbContext()) { var user = db.Users.Where(a => a.ResetPasswordCode == obj.ResetCode).FirstOrDefault(); if (user != null) { user.Password = Crypto.Hash(obj.NewPassword); user.ResetPasswordCode = ""; db.SaveChanges(); ModelState.AddModelError("ConfirmPassword", "Changes committed successfully"); } } } return View(); }
ViewModel 类
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace CI_Platform.Entities.Models; public partial class PasswordReset { [Required(ErrorMessage = "New password required", AllowEmptyStrings = false)] [DataType(DataType.Password)] public string? NewPassword { get; set; } [Compare("NewPassword", ErrorMessage = "New password and confirm password does not match")] [DataType(DataType.Password)] public string? ConfirmPassword { get; set; } [Required] public string? ResetCode { get; set; } }
问题原因及解决方法
核心原因
提交后ResetCode变为Null,主要是因为视图没有将ResetCode作为表单字段提交到后台,或者Post方法返回视图时没有传递包含ResetCode的ViewModel,导致字段丢失。
解决步骤
- 在视图中添加隐藏字段保存ResetCode
确保表单提交时携带ResetCode值,在ResetPassword视图里添加隐藏字段:
@model CI_Platform.Entities.Models.PasswordReset <!-- 或者对应你的ResetPasswordVM类 --> <form asp-action="ResetPassword" method="post"> @Html.AntiForgeryToken() <!-- 新密码输入框 --> <div class="form-group"> <label asp-for="NewPassword"></label> <input asp-for="NewPassword" class="form-control" /> <span asp-validation-for="NewPassword" class="text-danger"></span> </div> <!-- 确认密码输入框 --> <div class="form-group"> <label asp-for="ConfirmPassword"></label> <input asp-for="ConfirmPassword" class="form-control" /> <span asp-validation-for="ConfirmPassword" class="text-danger"></span> </div> <!-- 隐藏字段保存ResetCode --> <input type="hidden" asp-for="ResetCode" /> <button type="submit" class="btn btn-primary">提交</button> </form>
- 修改Post方法的返回逻辑
当ModelState无效或用户不存在时,返回视图要传递当前的ViewModel,确保ResetCode不会丢失:
[HttpPost] [AutoValidateAntiforgeryToken] public IActionResult ResetPassword(ResetPasswordVM obj) { if (ModelState.IsValid) { using (CiPlatformDbContext db = new CiPlatformDbContext()) { var user = db.Users.Where(a => a.ResetPasswordCode == obj.ResetCode).FirstOrDefault(); if (user != null) { user.Password = Crypto.Hash(obj.NewPassword); user.ResetPasswordCode = ""; db.SaveChanges(); ModelState.AddModelError("ConfirmPassword", "修改成功"); } else { ModelState.AddModelError(string.Empty, "无效的重置码"); } } } // 传递obj返回视图,保留ResetCode值 return View(obj); }
- 检查ViewModel命名一致性
注意控制器中使用的ResetPasswordVM和你提供的PasswordReset类是否为同一个类,若为不同类,需确保ResetPasswordVM包含ResetCode、NewPassword、ConfirmPassword属性及对应的验证特性,避免因类不匹配导致参数绑定失败。
内容的提问来源于stack exchange,提问作者Yuu
相关产品推荐
相关产品推荐

