令牌为null导致无效的ModelState

时间:2018-02-02 17:16:33

标签: c# asp.net-core token

我有一个允许用户重置密码的模型:

d = diff(A(1,:))==0
goodIdx = ~([d',false]|[false,d'])

通过以下操作方法设置令牌:

PUBLISH

电子邮件重定向到以下视图:

public class PasswordResetViewModel
{
    [Required]
    [EmailAddress(ErrorMessage = "Please ensure requestor email is valid")]
    [UIHint("email")]
    public string Email { get; set; }
    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }
    [Required]
    [DataType(DataType.Password), Compare("Password")]
    public string ConfirmPassword { get; set; }
    [Required]
    public string Token { get; set; }
}

但是,在提交时,令牌在以下操作项中为空,从而导致无效的ModelState

[AllowAnonymous]
        public async Task<IActionResult> PasswordResetEmail(UserEmailViewModel model)
        {
            if (ModelState.IsValid)
            {
                AppUser user = await userManager.FindByEmailAsync(model.Email);
                if (user == null)
                {
                    // Don't reveal that the user does not exist or is not confirmed
                    TempData["message"] = null;
                    return View("Login"); 
                }

                var token = userManager.GeneratePasswordResetTokenAsync(user).Result;
                var resetLink = Url.Action("PasswordReset", "Account", new { token = token }, protocol: HttpContext.Request.Scheme);
                var message = "<a href=\"" + resetLink + "\">Click here to reset your password</a>";
                string subjectLine = "Reset your password";
                //send email with email service
                emailService.SendHtmlEmail(message, user.Email, subjectLine);

                TempData["message"] = $"Check email for password reset link";
                return View("Login");
            }

            // If we got this far, something failed, redisplay form
            return View("ForgotPassword");
        }

电子邮件链接有效并且似乎具有有效令牌。但是,此标记值未在@model PasswordResetViewModel @{ ViewBag.Title = "Reset Password"; Layout = "_Layout"; } <div class="bg-primary panel-body"><h4>ViewBag.Title</h4></div> <div class="text-danger" asp-validation-summary="All"></div> <form asp-controller="Account" asp-action="PasswordReset" method="post"> <input type="hidden" asp-for="Token" /> <div class="form-group"> <label asp-for="Email"></label> <input asp-for="Email" class="form-control" /> </div> <div class="form-group"> <label asp-for="Password"></label> <input asp-for="Password" class="form-control" /> </div> <div class="form-group"> <label asp-for="ConfirmPassword"></label> <input asp-for="ConfirmPassword" class="form-control" /> </div> <button class="btn btn-primary btn-space" type="submit">Reset Password</button> </form> 操作方法中从View传递到控制器。

以下是呈现的HTML

[HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> PasswordReset(PasswordResetViewModel obj)
        {
            if (ModelState.IsValid)
            {
                AppUser user = await userManager.FindByEmailAsync(obj.Email);
                if (user != null)
                {
                    IdentityResult result = await userManager.ResetPasswordAsync(user, obj.Token, obj.Password);

                    if (result.Succeeded)
                    {
                        TempData["message"] = $"Password reset successful!";
                        return View("Login");
                    }
                    else
                    {
                        AddErrorsFromResult(result);
                        TempData["message"] = $"Error while resetting the password. Password was not reset. Send another reset password and try again";
                        return View("ForgotPassword");
                    }
                }
            else //user email not found in database
            {
                TempData["message"] = $"Error while resetting the password. Password was not reset. Send another reset password and try again";
                return View("ForgotPassword");
            }
        }

我尝试将线路更改为

PasswordReset

如果<div class="bg-primary panel-body"><h4>ViewBag.Title</h4></div> <div class="text-danger validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li> </ul></div> <form method="post" action="/Account/PasswordReset"> <input type="hidden" data-val="true" data-val-required="The Token field is required." id="Token" name="Token" value="" /> <div class="form-group"> <label for="Email">Email</label> <input class="form-control" type="email" data-val="true" data-val-email="Please ensure requestor email is valid" data-val-required="The Email field is required." id="Email" name="Email" value="" /> </div> <div class="form-group"> <label for="Password">Password</label> <input class="form-control" type="password" data-val="true" data-val-required="The Password field is required." id="Password" name="Password" /> </div> <div class="form-group"> <label for="ConfirmPassword">ConfirmPassword</label> <input class="form-control" type="password" data-val="true" data-val-equalto="&#x27;ConfirmPassword&#x27; and &#x27;Password&#x27; do not match." data-val-equalto-other="*.Password" data-val-required="The ConfirmPassword field is required." id="ConfirmPassword" name="ConfirmPassword" /> </div> <button class="btn btn-primary btn-space" type="submit">Reset Password</button> <input name="__RequestVerificationToken" type="hidden" value="CfDJ8P701H9_W2VHikt7vFU7qE_hDXNPQe-vU2zRITMm_SakSlqmLU7lTfycwmVg4bPhvqWHdv7d3n4YbJYOMqCVK55Rn0KqQCoZplL9a_eZDF48oiQExiaSTn4BcXdfhzWqjc1oQgyUQTyCbt1Zu1zhrva5dWPXXhXtxF442_Zn11GL8zBiqEsscAt2VbpcmkjJ8g" /></form> 参数区分大小写,但它没有修复它。

1 个答案:

答案 0 :(得分:1)

您应该使用Get Action方法进行token参数!与以下代码一样,填充Token方法中ViewModel的{​​{1}}属性并将其传递给Get,否则它将为空:

View

现在手动调用[HttpGet] [AllowAnonymous] public async Task<IActionResult> PasswordReset(string token) { //Other codes var vm = new PasswordResetViewModel(); vm.Token = token; return View("ForgotPassword", vm); } 链接(例如:ResetPassword)并查看呈现的HTML。 http://localhost:PORT/Account/ResetPassword?token=123456字段的隐藏输入应具有以下值:Token