经过大量的捣乱,并得到了ADyson的一些出色帮助,我得到了这个。
在我的系统上,当管理员用户登录时,会出现一个链接,供他们进入用户管理系统。这提供了用户列表,创建其他用户,删除或更改其详细信息的功能。
此外,当任何用户登录时,他们都可以更改自己的密码。但是,如果用户忘记了密码,则admin用户必须重置密码。我没有给他们发电子邮件或任何想象的东西。在管理界面屏幕的“列出用户”位中,有一个“操作”列,其中包含编辑,删除,显示详细信息和重置密码的链接。
我有一个ApplicationUsersController,它包含编辑,删除等功能。我有一系列的ApplicationUsers视图叫做Create,Edit,Delete,Details,Edit,Index。大多数代码是在创建ApplicationUsersController并选择创建视图时生成的。还有一个ResetUserPasswordsViewModel。这是ResetPassword视图:
@model ICWeb.Models.ResetUserPasswordViewModel
@{
ViewBag.Title = "Reset User Password";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "Please fix the errors displayed", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.NewPassword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.NewPassword, new { htmlAttributes = new { @class = "form-control", @autofocus = "autofocus" } })
@Html.ValidationMessageFor(model => model.NewPassword, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Reset Password" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
在控制器中我有:
// GET: /ApplicationUsers/ResetPassword
public ActionResult ResetPassword(string id)
{
return View(new ResetUserPasswordViewModel() { Id = id });
}
//POST: /ApplicationUsers/ResetPassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetUserPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
ApplicationDbContext context = new ApplicationDbContext();
UserStore<ApplicationUser> store = new UserStore<ApplicationUser>(context);
UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(store);
string userId = model.Id;
string newPassword = model.NewPassword;
string hashedNewPassword = UserManager.PasswordHasher.HashPassword(newPassword);
ApplicationUser cUser = await store.FindByIdAsync(userId);
await store.SetPasswordHashAsync(cUser, hashedNewPassword);
await store.UpdateAsync(cUser);
return RedirectToAction("Index");
}
经过大量的捣乱,我重新做了这个功能。视图现在加载,我可以输入2个新密码。当我提交时,ResetPassword函数运行。我可以看到,当我单步执行代码时,它会输入我输入的密码,通过编辑GET函数以使用Id填充模型,我现在可以获得用户的ID。整个控制器访问仅限于具有管理员权限的用户,因此,除非您是管理员,否则您无法在此处执行任何操作。
在我的ResetUserPasswordModel中,我有:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace ICWeb.Models
{
public class ResetUserPasswordViewModel
{
public string Id { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
}
全部排序,帮助过,非常感谢。
答案 0 :(得分:0)
在我正在开发的系统中(但尚未完成或测试)我已经写好了。它的工作原理应该是一个很好的起点。请注意,视图模型会处理不匹配的密码,因此您已经了解它。
我对用户管理器使用直接注入 - 只需将我的_userManager替换为您自己的实例,但是您可以创建它。
@model Models.ResetPasswordViewModel
@{
ViewBag.Title = "Reset password";
}
<div class="container">
@if (ViewBag.Error != null)
{
<div class="alert-danger mb-2">Error(s) occured : @ViewBag.Error</div>
@Html.ActionLink("Back to List", "AllUsers", null, new { @class = "btn btn-outline-primary" })
}
else
{
using (Html.BeginForm("ResetPassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary("", new { @class = "text-danger" })
@Html.HiddenFor(x => x.Id)
<div class="form-group">
@Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control", @readonly = "" } })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Password, new { @class = "control-label" })
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.ConfirmPassword, new { @class = "control-label" })
@Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
</div>
<div class="form-group d-flex">
@Html.ActionLink("Back to User Edit", "EditUser", "Account", new { userId = Model.Id }, new { @class = "btn btn-outline-primary" })
<input type="submit" value="Reset Password" class="btn btn-primary ml-auto" />
</div>
}
}
</div>
public class ResetPasswordViewModel
{
[Display(Name = "User Id")]
public string Id { get; set; }
[Display(Name = "User Name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = _userManager.FindById(model.Id);
IdentityResult result = null;
if (user != null)
{
string code = await _userManager.GeneratePasswordResetTokenAsync(user.Id);
result = await _userManager.ResetPasswordAsync(user.Id, code, model.Password);
if (result.Succeeded)
{
return RedirectToAction("ResetPasswordConfirmation", "Account", model);
}
}
// return errors
var s = new System.Text.StringBuilder();
//
foreach (var e in result.Errors)
{
if (s.Length > 0)
{
s.Append(", ");
}
s.Append(e);
}
ViewBag.Error = s.ToString();
return View();
}