ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

.NET 6 + EF Core + MySQL + Docker + Identity +MVC 学习笔记 (三)

2022-07-11 22:00:09  阅读:165  来源: 互联网

标签:Index Core EF userManager MVC user new btn public


环境准备:

1、VS 2022 免费社区版

 

本章目标:

  1、增加 用户 列表显示页面;

  2、增加 角色 维护主页面;

  3、增加 编辑 角色下属 用户 界面;

  4、

 

1、增加 用户列表 显示页面

   新建一个 UserAdmin的控制器:

  

    就选择 MVC 控制器-空:

       

   名称: UserAdminController

       

  打开UserAdminController.cs后,在默认的 Index 右键选择 添加视图:

       

   简单一点,就用空视图: 

      

    名字不用改,就Index.cshtml 

      

  会自动在 Views目录下,增加 UserAdmin 目录,并增加空的 Index.cshtml ,并自动打开:

      

  在Index.cshtml 视图中插入 显示用户列表的 View,代码如下:

@using Microsoft.AspNetCore.Identity
@model IEnumerable<IdentityUser>
@{
    ViewBag.Title = "Index";
}
<div class="panel panel-primary">
    <div class="panel-heading">
        用户列表
    </div>
    <table class="table table-striped">
        <tr><th>Name</th><th>Email</th><th>PhoneNumber</th><th></th></tr>
        @if (Model.Count() == 0)
        {
            <tr><td colspan="4" class="text-center">无用户</td></tr>
        }
        else
        {
            foreach (IdentityUser user in Model)
            {
                <tr>        
                    <td>@user.UserName</td>
                    <td>@user.Email</td>
                    <td>@user.PhoneNumber</td>
                    <td>
                            @Html.ActionLink("密码重置", "ResetPassword", new { id = user.Id },
                                new { @class = "btn btn-warning btn-xs" })
                            @Html.ActionLink("编辑", "Edit", new { id = user.Id },
                                new { @class = "btn btn-primary btn-xs" })
                            @Html.ActionLink("删除", "Delete", new { id = user.Id },
                            new { @class = "btn btn-danger btn-xs" })
                    </td>
                </tr>
            }
        }
    </table>
</div>

  修改 UserAdminController ,先把 UserManager 传入,再修改 Index View的返回为所有 User:

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace POSystem.Controllers
{
    public class UserAdminController : Controller
    {
        private readonly UserManager<IdentityUser> _userManager;

        public UserAdminController(UserManager<IdentityUser> userManager)
        {
            _userManager = userManager;
        }

        public IActionResult Index()
        {
            return View(_userManager.Users);
        }
    }
}

  先把这个UserAdmin的按钮入口 放在 Home和Privacy菜单的中间,修改_Layout.cshtml 

          <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="UserAdmin" asp-action="Index">用户管理</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                    <partial name="_LoginPartial" />
                </div>

  列表效果:

 

   注:密码重置、编辑、删除 待补充。

 

 

 

2、增加 角色 维护主页面;

  增加一个角色维护管理页面来为用户分配角色;先添加一个RoleAdminController 控制器:

       

   同样再加个Index View:

       

    修改 RoleAdminController,  传入 RoleManager, Index返回所有Role给View:

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace POSystem.Controllers
{
    public class RoleAdminController : Controller
    {
        private readonly RoleManager<IdentityRole> _roleManager;

        public RoleAdminController(RoleManager<IdentityRole> roleManager)
        {
            _roleManager = roleManager;
        }
        public IActionResult Index()
        {
            return View(_roleManager.Roles);
        }
    }
}

   修改Index View,先最简单的显示一个列表:

@using Microsoft.AspNetCore.Identity
@model IEnumerable<IdentityRole>
@{
    ViewBag.Title = "Index";
}
<div class="panel panel-primary">
    <div class="panel-heading">
        角色列表
    </div>
    <table class="table table-striped">
        <tr><th>Name</th><th></th></tr>
        @if (Model.Count() == 0)
        {
            <tr><td colspan="4" class="text-center">无角色</td></tr>
        }
        else
        {
            foreach (IdentityRole role in Model)
            {
                <tr>
                    <td>@role.Name</td>                    
                    <td>                        
                        @Html.ActionLink("编辑", "Edit", new { id = role.Id },
                            new { @class = "btn btn-primary btn-xs" })
                        @Html.ActionLink("删除", "Delete", new { id = role.Id },
                        new { @class = "btn btn-danger btn-xs" })
                    </td>
                </tr>
            }
        }
    </table>
</div>@Html.ActionLink("新建", "Create","RoleAdmin",null, new { @class = "btn btn-primary btn-xs" })

    继续修改  _Layout.cshtml :

                 <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="UserAdmin" asp-action="Index">用户管理</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="RoleAdmin" asp-action="Index">角色管理</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                    <partial name="_LoginPartial" />
                </div>

  跑起来看到有角色管理这个按钮了:

    但是一点就出错:

    初步研究,应该是没有加这个:

 

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddEntityFrameworkStores<ApplicationDbContext>();

  加完,能正常显示RoleAdmin的Index:

 

   在RoleAdmin 控制器中增加 Create Action :

        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public async Task<ActionResult> Create([Required] string name)
        {
            if (ModelState.IsValid)
            {
                IdentityResult result = await _roleManager.CreateAsync(new IdentityRole(name));
                if (result.Succeeded)
                {
                    return RedirectToAction("Index");
                }
                else
                {
                    AddErrorsFromResult(result);
                }
            }
            return View();
        }

        private void AddErrorsFromResult(IdentityResult result)
        {
            foreach (IdentityError error in result.Errors)
            {
                ModelState.AddModelError("", error.Description);
            }
        }

  再为Create Action 添加一个空视图,并把以下视图代码加入:

@model string
@{ ViewBag.Title = "新增角色";}
<h2>新增角色</h2>
@Html.ValidationSummary(false)
@using (Html.BeginForm())
{
    <div class="form-group">
        <label>Name</label>
        <input name="name" value="@Model" class="form-control" />
    </div>
    <button type="submit" class="btn btn-primary">新增</button>
    @Html.ActionLink("取消", "Index", "RoleAdmin", null, new { @class = "btn btn-default btn-xs" })
}

  运行后,点击 新建 按钮:

 

  建一个 Admin 、ReadOnlyUser 、OperationUser :

3、增加 编辑 角色下属 用户 界面;

  考虑在角色界面,显示每个角色对应的用户;并增加角色维护用户页面(即 编辑 页面)

  先增加两个ViewModel: 

using Microsoft.AspNetCore.Identity;

namespace POSystem.Models
{
    public class RoleViewModel
    {
        public IdentityRole Role { get; set; }
        public IEnumerable<IdentityUser> Members { get; set; }
        public IEnumerable<IdentityUser> NonMembers { get; set; }
    }
}
using System.ComponentModel.DataAnnotations;

namespace POSystem.Models
{
    public class RoleModificationModel
    {
        [Required]
        public string RoleName { get; set; }
        public string[]? IdsToAdd { get; set; }
        public string[]? IdsToDelete { get; set; }
    }
}
        private readonly RoleManager<IdentityRole> _roleManager;
        private readonly UserManager<IdentityUser> _userManager;

        public RoleAdminController(RoleManager<IdentityRole> roleManager, UserManager<IdentityUser> userManager)
        {
            _roleManager = roleManager;
            _userManager = userManager;
        }    

  RoleAdmin改写成以上,首先是把  RoleManager<IdentityRole> roleManager, UserManager<IdentityUser> userManager  传进来;

  增加 Edit 两个Action, 一个HTTP GET 一个对应HTTP POST:

        public async Task<ActionResult> Edit(string id)
        {
            IdentityRole role = await _roleManager.FindByIdAsync(id);

            IEnumerable<IdentityUser> members
                    = await _userManager.GetUsersInRoleAsync(role.Name);

            List<IdentityUser> nonMembers = new List<IdentityUser>();
            foreach (IdentityUser user in _userManager.Users)
            {
                if (!members.Any(x => x.Id.Equals(user.Id)))
                {
                    nonMembers.Add(user);
                }
            }

            return View(new RoleViewModel
            {
                Role = role,
                Members = members,
                NonMembers = nonMembers
            });
        }


        [HttpPost]
        public async Task<ActionResult> Edit(RoleModificationModel model)
        {
            IdentityResult result;
            if (ModelState.IsValid)
            {
                foreach (string userId in model.IdsToAdd ?? new string[] { })
                {
                    var user = await _userManager.FindByIdAsync(userId);

                    result = await _userManager.AddToRoleAsync(user, model.RoleName);
                    if (!result.Succeeded)
                    {
                        return View("Error", result.Errors);
                    }
                }
                foreach (string userId in model.IdsToDelete ?? new string[] { })
                {
                    var user = await _userManager.FindByIdAsync(userId);
                    result = await _userManager.RemoveFromRoleAsync(user,
                       model.RoleName);
                    if (!result.Succeeded)
                    {
                        return View("Error", result.Errors);
                    }
                }
                return RedirectToAction("Index");
            }
            return View("Error", new string[] { "Role Not Found" });
        }

  增加Edit的视图,用空视图,然后用以下代码代替:

@using POSystem.Models
@using Microsoft.AspNetCore.Identity
@model RoleViewModel
@{ ViewBag.Title = "Edit Role";}
@Html.ValidationSummary()
@using (Html.BeginForm())
{
    <input type="hidden" name="roleName" value="@Model.Role.Name" />
    <div class="panel panel-primary">
        <div class="panel-heading">添加用户至角色:@Model.Role.Name</div>
        <table class="table table-striped">
            @if (Model.NonMembers.Count() == 0)
            {
                <tr><td colspan="2">所有用户已添加</td></tr>
            }
            else
            {
                <tr><td>用户名</td><td>添加至角色</td></tr>
                foreach (IdentityUser user in Model.NonMembers)
                {
                    <tr>
                        <td>@user.UserName</td>
                        <td>
                            <input type="checkbox" name="IdsToAdd" value="@user.Id">
                        </td>
                    </tr>
                }
            }
        </table>
    </div>
    <div class="panel panel-primary">
        <div class="panel-heading">从角色:@Model.Role.Name 中移除用户</div>
        <table class="table table-striped">
            @if (Model.Members.Count() == 0)
            {
                <tr><td colspan="2">无下属用户</td></tr>
            }
            else
            {
                <tr><td>用户名</td><td>从角色中移除</td></tr>
                foreach (IdentityUser user in Model.Members)
                {
                    <tr>
                        <td>@user.UserName</td>
                        <td>
                            <input type="checkbox" name="IdsToDelete" value="@user.Id">
                        </td>
                    </tr>
                }
            }
        </table>
    </div>
    <button type="submit" class="btn btn-primary">保存</button>
    @Html.ActionLink("取消", "Index", null, null, new { @class = "btn btn-default" })
}

  点击 ReadOnlyUser 角色的编辑按钮,可以勾选用户添加至角色:

 

 

   上一步点保存后,再点击 ReadOnlyUser 角色的编辑按钮,可以看到 已经在角色列表,并可以勾选移除:

  为了直观的显示每个角色下面有哪些用户,则考虑修改Index Action和视图: 

        public async Task<IActionResult> Index()
        {
            List<RoleViewModel> roleviewmodels = new List<RoleViewModel>();
            foreach (IdentityRole role in _roleManager.Roles.ToList())
            {
                RoleViewModel newrole = new RoleViewModel();
                newrole.Role = role;
                newrole.Members = await _userManager.GetUsersInRoleAsync(role.Name);
                roleviewmodels.Add(newrole);
            }
            return View(roleviewmodels);
        }

  此处有个 MySQL 和 MSSQL不同的地方,如果红色的 .ToList() 不加,则会报错,提示: 

InvalidOperationException: This MySqlConnection is already in use. See https://fl.vu/mysql-conn-reuse

  最后经过查询,知道MySQL不支持一个特性:MultipleActiveResultSets  

   修改Index 视图如下:

@using Microsoft.AspNetCore.Identity
@model IEnumerable<RoleViewModel>
@{
    ViewBag.Title = "Index";
}
<div class="panel panel-primary">
    <div class="panel-heading">
        角色列表
    </div>
    <table class="table table-striped">
        <tr><th>角色名</th><th>下属用户</th><th></th></tr>
        @if (Model.Count() == 0)
        {
            <tr><td colspan="4" class="text-center">无角色</td></tr>
        }
        else
        {
            foreach (RoleViewModel roleview in Model)
            {
                <tr>
                    <td>@roleview.Role.Name</td>
                    <td>
                        @foreach (IdentityUser user in @roleview.Members)
                        {
                            @user.UserName@Html.Label(";")                            
                        }
                    </td>
                    <td>@Html.ActionLink("编辑", "Edit", new { id = roleview.Role.Id },new { @class = "btn btn-primary btn-xs" })
                        @Html.ActionLink("删除", "Delete", new { id = roleview.Role.Id },new { @class = "btn btn-danger btn-xs" })
                    </td>
                </tr>
            }
        }
    </table>
</div>
@Html.ActionLink("新建", "Create","RoleAdmin",null, new { @class = "btn btn-primary btn-xs" })

  最后体现结果:

 

标签:Index,Core,EF,userManager,MVC,user,new,btn,public
来源: https://www.cnblogs.com/jacky-zhang/p/16452832.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有