• asp.net Identity2 角色(Role)的使用(三)用户管理,用户控制器和视图


    修改用户控制器AccountController,增加角色管理器。

    public class AccountController : Controller
    {

    public AccountController()
    {
    }

    public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, ApplicationRoleManager roleManager )
    {
    UserManager = userManager;
    SignInManager = signInManager;
    RoleManager = roleManager;
    }

    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager
    {
    get
    {
    return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
    }
    private set
    {
    _userManager = value;
    }
    }


    private ApplicationRoleManager _roleManager;
    public ApplicationRoleManager RoleManager
    {
    get
    {
    return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
    }
    set
    {
    _roleManager = value;
    }

    }

    1、登录

    控制器:

    [AllowAnonymous]   //允许匿名访问,asp.net MVc5 中,只要操作方法有[AllowAnonymous]的数据注解,不管控制器的授权限制,都可实现匿名访问此操作方法。 
    public ActionResult Login(string returnUrl)
    {
    ViewBag.ReturnUrl = returnUrl;
    return View();
    }

    // POST: /Account/Login
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model)
    {
    if (!ModelState.IsValid)
    {
    return View(model);
    }

    var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
    switch (result)
    {
    case SignInStatus.Success:

    if (User.IsInRole("Expert") || User.IsInRole("Student"))    //对于不同的角色登录成功后跳转不同的页面。
    {
    return RedirectToAction("Index", "Home", new { area = "" });
    }
    else
    {
    return RedirectToAction("Index", "Home", new { area = "Admin" });
    }
    case SignInStatus.LockedOut:
    return View("Lockout");
    case SignInStatus.Failure:
    default:
    ModelState.AddModelError("", "用户名或者密码不正确。");
    return View(model);
    }
    }

    用户列表,显示所有用户,以及每个用户所拥有的角色名。

    模型:

    public class EditUserViewModel
    {
    [Display(Name = "用户ID")]
    public string Id { get; set; }

    [Required(AllowEmptyStrings=false)]
    [Display(Name = "用户名")]
    [StringLength(20, ErrorMessage = "{0}至少包含{2}个字符", MinimumLength = 6)]
    public string UserName { get; set; }

    [Required]
    [EmailAddress]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "电子邮件")]
    public string Email { get; set; }

    [Required]
    [StringLength(20, ErrorMessage = "{0}少于{2}个字符", MinimumLength = 2)]
    [Display(Name = "姓名")]
    public string RealName { get; set; }

    [Display(Name = "性别")]
    [Required]
    public Gender Gender { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "出生日期")]
    public DateTime Birthday { get; set; }

    public IEnumerable<System.Web.Mvc.SelectListItem> RolesList { get; set; }   //使用SelectListItem 的泛型 集合,虽然在用户列表中不需要显示选中的角色,但这里也可以使用SelectListItem 泛型集合。

    }

    控制器:

    //GET:/Account/Index
    [Authorize(Roles = "SuperAdmin,Teacher")]
    public async Task<ActionResult> Index()
    {
    var usersViewModel = new List<EditUserViewModel>();
    foreach (var user in await UserManager.Users.OrderBy(u =>u.UserName).ToListAsync())
    {
    var userRoles =await UserManager.GetRolesAsync(user.Id);
    var _userViewModel = new EditUserViewModel
    {
    Id = user.Id,
    UserName = user.UserName,
    Email = user.Email,
    RealName = user.RealName,
    Gender = user.Gender,
    Birthday = user.Birthday,
    RolesList = RoleManager.Roles.Where(x => userRoles.Contains(x.Name))  //满足所有角色中 此用户包含的角色,并建立投影 选择该角色的ID,和角色的名字。
    .Select(x => new SelectListItem
    {
    Text = x.Name,
    Value = x.Id
    })

    };
    usersViewModel.Add(_userViewModel);
    }

    视图:

    @model IEnumerable<MajorConstruction.Areas.Admin.Models.EditUserViewModel>
    @{
    ViewBag.Title = "用户列表";
    }
    @using Microsoft.AspNet.Identity
    <h2>@ViewBag.Title</h2>

    @if (User.IsInRole("SuperAdmin"))
    {
    <p>
    @Html.ActionLink("新建用户", "Register", null, new { @class = "btn btn-primary" })
    </p>
    }

    <hr />
    <table class="table table-hover table-striped">
    <thead>
    <tr>
    <th>
    @Html.DisplayName("用户名")
    </th>
    <th>
    @Html.DisplayNameFor(model => model.RealName)
    </th>
    <th>
    @Html.DisplayNameFor(model => model.Gender)
    </th>
    <th>
    @Html.DisplayNameFor(model => model.Birthday)
    </th>
    <th>
    @Html.DisplayNameFor(model => model.Email)
    </th>
    <th>
    该用户拥有的角色
    </th>

    <th></th>
    </tr>
    </thead>
    <tbody>
    @foreach (var item in Model)
    {
    <tr>
    <td>
    @Html.DisplayFor(modelItem => item.UserName)
    </td>
    <td>
    @Html.DisplayFor(modelItem => item.RealName)
    </td>
    <td>
    @Html.DisplayFor(modelItem => item.Gender)
    </td>
    <td>
    @Html.DisplayFor(modelItem => item.Birthday)
    </td>
    <td>
    @Html.DisplayFor(modelItem => item.Email)
    </td>
    <td>
    @if (item.RolesList != null)
    {
    foreach (var roleItem in item.RolesList)  //只需要列出
    {
    <text> @roleItem.Text |</text>

    }
    }
    </td>
    <td>
    @if (User.IsInRole("SuperAdmin") && item.UserName != "administrator" && item.UserName != User.Identity.GetUserName())
    {
    @Html.ActionLink("修改信息", "EditUser", new { id = item.Id }, new { @class="btn btn-primary btn-xs",role="button"})
    <text> </text>
    @Html.ActionLink("重置密码", "ChangeUserPassword", new { id = item.Id }, new { @class = "btn btn-primary btn-xs", role = "button" })
    <text> </text>
    @Html.ActionLink("删除", "Delete", new { id = item.Id }, new { @class = "btn btn-primary btn-xs", role = "button" })

    }
    </td>
    </tr>
    }
    </tbody>

    </table>

    创建用户并分配角色

    控制器:

    // GET: Admin/Account/Register //添加用户,只有管理员角色能够添加用户。
    [Authorize(Roles = "SuperAdmin")]
    public async Task<ActionResult> Register()
    {
    ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Description");
    return View();
    }
    //
    // POST: /Account/Register
    [Authorize(Roles = "SuperAdmin")]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model,params string[] selectedRoles) //可变数组参数。 模型绑定自动完成,给selectedRoles 可变参数数组传入参数。
    {
    if (ModelState.IsValid)
    {
    var user = new ApplicationUser { UserName = model.UserName, Email = model.Email, RealName = model.RealName, Gender = model.Gender, Birthday = model.Birthday, };
    var userresult = await UserManager.CreateAsync(user, model.Password); //在数据库中创建了这个用户,那么就生成了UserID 了。

    //给用户添加角色
    if (userresult.Succeeded)

    if (selectedRoles != null)
    {
    var result = await UserManager.AddToRolesAsync(user.Id, selectedRoles);
    if (!result.Succeeded)
    {
    ModelState.AddModelError("", result.Errors.First());
    ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Description");
    return View(model);
    }

    }

    }

    else
    {
    ModelState.AddModelError("", userresult.Errors.First());
    ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Description");
    return View(model);
    }

    return RedirectToAction("Index"); //此处用得好。如果用户创建成功,但没有角色参数,则返回index.2、如果用户创建成功,角色添加成功,也返回index;
    }

    // 如果我们进行到这一步时某个地方出错,则重新显示表单
    ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "Description");
    return View(model);
    }

    视图:

    @model MajorConstruction.Areas.Admin.Models.RegisterViewModel
    @{
    ViewBag.Title = "创建新账户";

    }

    <h2>@ViewBag.Title。</h2>

    @using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
    {
    @Html.AntiForgeryToken()
    <hr />
    @Html.ValidationSummary("", new { @class = "text-danger" })
    <div class="form-group">
    @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
    @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
    </div>
    </div>

    <div class="form-group">
    @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
    @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
    </div>
    </div>

    <div class="form-group">
    <label class="col-md-2 control-label">
    选择用户角色
    </label>
    <div class="col-md-10">
    @foreach (var item in (SelectList)ViewBag.RoleID)   //遍历get方法返回的角色名称和角色描述。
    {
    <div class="checkbox">
    <label>
    <input type="checkbox" name="selectedRoles" value="@item.Value" />
    @item.Text
    </label>
    </div>
    }
    </div>
    </div>

    <div class="form-group">
    <div class="col-md-offset-2 col-md-10">
    <input type="submit" class="btn btn-default" value="新建" />
    </div>
    </div>
    }

    @section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    }

    管理员修改其它用户的信息

    控制器:

    //GET Account/EditUser 系统管理员修改其他人的信息
    [Authorize(Roles = "SuperAdmin")]
    public async Task<ActionResult> EditUser(string Id)
    {
    if(string.IsNullOrEmpty(Id))
    {
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    var _user = await UserManager.FindByIdAsync(Id);
    if (_user == null)
    {
    return HttpNotFound();
    }

    var userRoles = await UserManager.GetRolesAsync(_user.Id);

    var editUser = new EditUserViewModel
    {
    Id = _user.Id,
    UserName = _user.UserName,
    Email = _user.Email,
    RealName = _user.RealName,
    Gender = _user.Gender,
    Birthday = _user.Birthday,
    RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem() //建立一个投影,如果角色中包含当前用户的角色,就选中此角色。
    {
    Selected =userRoles.Contains(x.Name),
    Text =x.Description,
    Value =x.Name
    })

    };
    return View(editUser);

    }

    //POST:// Admin/Account/EditUser/5 系统管理员修改其他人的信息
    [Authorize(Roles = "SuperAdmin")]
    [ValidateAntiForgeryToken]
    [HttpPost]
    public async Task<ActionResult> EditUser([Bind(Include = "Id,UserName,Email,RealName,Gender,Birthday")]EditUserViewModel user, params string[] selectedRole)
    {
    if (ModelState.IsValid)
    {
    var _user = await UserManager.FindByIdAsync(user.Id);
    if (_user == null)
    {
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    _user.UserName=user.UserName;
    _user.Email = user.Email;
    _user.Email=user.Email;
    _user.RealName = user.RealName;
    _user.Gender=user.Gender;
    _user.Birthday = user.Birthday;


    var userRoles = await UserManager.GetRolesAsync(_user.Id);
    selectedRole = selectedRole ?? new string[]{};

    var result = await UserManager.AddToRolesAsync(user.Id, selectedRole.Except(userRoles).ToArray<string>());  //增加选中并且以前没有的角色组。然后转换成字符串数组。
    if (!result.Succeeded)
    {
    ModelState.AddModelError("", result.Errors.First());
    return View(user);
    }

    result = await UserManager.RemoveFromRolesAsync(user.Id, userRoles.Except(selectedRole).ToArray<string>()); //减少发前有的,但本次未选中的角色组

    if (!result.Succeeded)
    {
    ModelState.AddModelError("", result.Errors.First());
    return View(user);

    }

    UserManager.Update(_user); //这个语句是否有必要要呢?
    return RedirectToAction("Index");
    }

    ModelState.AddModelError("", "绑定失败");
    return View(user);

    }

    视图:

    @model MajorConstruction.Areas.Admin.Models.EditUserViewModel

    @{
    ViewBag.Title = "EditUser";
    }

    <h2>修改用户信息</h2>


    @using (Html.BeginForm())
    {
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.Id)

    <div class="form-group">
    @Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
    @Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } })
    @Html.ValidationMessageFor(model => model.UserName, "", new { @class = "text-danger" })
    </div>
    </div>

    <div class="form-group">
    @Html.Label("编辑用户角色", new { @class ="control-label col-md-2" })
    <div class="col-md-10">
    @foreach (var item in Model.RolesList)
    {
    string checkedOrNot =item.Selected ? "checked": null; //判定该角色是否被选中。
    <div class="checkbox">
    <label>
    <input type="checkbox" name="selectedRole" value="@item.Value" checked="@checkedOrNot">
    @item.Text
    </label>
    </div>

    }
    </div>
    </div>

    <div class="form-group">
    <div class="col-md-offset-2 col-md-10">
    <input type="submit" value="修改" class="btn btn-default" />
    </div>
    </div>
    </div>
    }


    @section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    }

    系统管理员修改他人的密码:

    控制器:

    //GET://Account/ChangeUserPassword //系统管理员修改其他用户的密码
    [Authorize(Roles = "SuperAdmin")]
    public ActionResult ChangeUserPassword(string Id)
    {
    var user = UserManager.FindById(Id);
    if (user == null)
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    else
    {
    ResetPasswordViewModel _resetPasswordViewModel = new ResetPasswordViewModel()
    {
    UserName = user.UserName
    };
    return View(_resetPasswordViewModel);
    }

    }

    //Post ://Account/ChangeUserPassword //系统管理员修改其他用户的密码
    [Authorize(Roles = "SuperAdmin")]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult ChangeUserPassword(ResetPasswordViewModel _resetPasswordViewModel)
    {
    if (!ModelState.IsValid)
    {
    return View(_resetPasswordViewModel);
    }

    var _user = UserManager.FindByName(_resetPasswordViewModel.UserName);
    if (_user == null)
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

    var code =UserManager.GeneratePasswordResetToken(_user.Id);    //给用户创建一个防伪造的密码  。                                       
    var result =UserManager.ResetPassword(_user.Id,code,_resetPasswordViewModel.Password); //重置密码。
    if (result.Succeeded)
    {
    return RedirectToAction("Index");

    }
    return View();


    }

    视图:

    @model MajorConstruction.Areas.Admin.Models.ResetPasswordViewModel

    @{
    ViewBag.Title = "更改用户密码";
    }

    <h2>@ViewBag.Title。</h2>


    @using (Html.BeginForm())
    {
    @Html.AntiForgeryToken()

    <div class="form-horizontal">

    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @*
    @Html.HiddenFor(model =>model.UserName)
    <div class="form-group">
    @Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
    <p class="form-control-static">
    @Html.DisplayFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } })
    </p>

    </div>
    </div>*@    //将某个值返回POst方法,不可更改它的值,有几种方法,以上注释的为第一种:静态控件显示,隐藏字段传递值。 显示的是文本。

    <div class="form-group">
    @Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
    <input type="text" value="@Model.UserName" class="form-control" readonly="readonly" name="UserName" id="UserName" />  //第二种方法:使用原始的Html标记<input  readonly ="readonly">,既可以传递表单值,又不更改表单里的数据。显示的是一个不可更改的表单值。
    </div>
    </div>

    用户修改自己的个人信息

    控制器:

    //Get://Account/Edit 修改登录用户自己的信息
    [Authorize(Roles = "SuperAdmin,Teacher")]
    public ActionResult Edit()
    {
    var _user = UserManager.FindById(User.Identity.GetUserId());
    if (_user == null)
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    else
    {
    var editViewModelUser= new EditViewModel
    {
    RealName=_user.RealName,Gender=_user.Gender,Email=_user.Email,Birthday=_user.Birthday

    };
    return View(editViewModelUser);
    }
    }

    //
    //Post: Account/Edit 修改登录用户自己的信息
    [Authorize(Roles = "SuperAdmin,Teacher")]
    [ValidateAntiForgeryToken]
    [HttpPost]
    public ActionResult Edit(EditViewModel user)
    {
    var _user = UserManager.FindById(User.Identity.GetUserId());
    if (_user == null)
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    if (ModelState.IsValid)
    {
    _user.RealName = user.RealName;
    _user.Gender = user.Gender;
    _user.Birthday = user.Birthday;
    _user.Email = user.Email;

    UserManager.Update(_user);
    return RedirectToAction("Index");
    }
    ModelState.AddModelError("","绑定失败");
    return View(user);


    }

    视图:

    @model MajorConstruction.Areas.Admin.Models.EditViewModel
    @using Microsoft.AspNet.Identity;
    @{
    ViewBag.Title = "个人信息修改";
    }

    <h2>@ViewBag.Title。</h2>

    @using (Html.BeginForm())
    {
    @Html.AntiForgeryToken()

    <div class="form-horizontal">

    <hr />
    @Html.ValidationSummary(true,"", new { @class = "text-danger" })

    <div class="form-group">
    <label class="control-label col-md-2"> 用户名:</label>
    <div class="col-md-10">
    <p class="form-control-static">@User.Identity.GetUserName()</p>  //静态控制显示get方法返回值。隐藏表单发送值。
    </div>
    </div>

    <div class="form-group">
    @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
    @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
    @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
    </div>
    </div>

    登录用户更改自己的密码:

    控制器:

    //GET:// Admin/Account/ChangePassword //登录用户修改自己的密码
    [Authorize(Roles = "SuperAdmin,Teacher")]
    public ActionResult ChangePassword()
    {
    var user = UserManager.FindById(User.Identity.GetUserId());
    if (user == null)
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    else
    {
    var changePasswordViewModel = new ChangePasswordViewModel();
    return View(changePasswordViewModel);
    }

    }

    //POST:// Admin/Account/ChangePassword //登录用户修改自己的密码
    [Authorize(Roles = "SuperAdmin,Teacher")]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult ChangePassword(ChangePasswordViewModel userViewModel)
    {
    var userId = User.Identity.GetUserId();
    var _user = UserManager.FindById(userId);
    if (ModelState.IsValid)
    {
    if (UserManager.CheckPassword(_user, userViewModel.OldPassword))  //使用UserManager.CheckPassword(user,oldpassword) 检查密码是否正确。
    {
    UserManager.RemovePassword(userId);             //修改密码的第二种方式:首先清空密码,再向该账户添加密码。
    UserManager.AddPassword(userId, userViewModel.NewPassword);
    return RedirectToAction("Index");
    }
    else
    {
    ModelState.AddModelError("", "输入的旧密码不正确");
    return View(userViewModel);
    }
    }
    else
    {
    ModelState.AddModelError("", "绑定失败");
    return View(userViewModel);
    }
    }

    视图:

    @model MajorConstruction.Areas.Admin.Models.ChangePasswordViewModel
    @using Microsoft.AspNet.Identity;
    @{
    ViewBag.Title = "个人密码修改";
    }
    <h2>@ViewBag.Title。</h2>

    @using (Html.BeginForm())
    {
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })

    <div class="form-group">
    @Html.Label("用户名", new { @class = "control-label col-md-2" })
    <div class="col-md-10">
    <p class="form-control-static"> @User.Identity.GetUserName()</p>
    </div>
    </div>

    <div class="form-group">
    @Html.LabelFor(model => model.OldPassword, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
    @Html.EditorFor(model => model.OldPassword, new { htmlAttributes = new { @class = "form-control" } })
    @Html.ValidationMessageFor(model => model.OldPassword, "", new { @class = "text-danger" })
    </div>
    </div>

  • 相关阅读:
    .NET Core 首例 Office 开源跨平台组件(NPOI Core)
    ASP.NET Core 导入导出Excel xlsx 文件
    python练习七—P2P下载
    VisualVM远程连接Tomcat
    一次Linux自动化部署尝试
    python练习六—简单的论坛
    shiro实现APP、web统一登录认证和权限管理
    python练习五—简单web应用
    python练习四—简单的聊天软件
    python练习三—解析xml
  • 原文地址:https://www.cnblogs.com/liuyuanhao/p/4537356.html
Copyright © 2020-2023  润新知