查看: 114|回复: 0

篇(19)-Asp.Net Core入门实战-权限管理之整理菜单导航控制 ...

[复制链接]

4

主题

8

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2023-1-16 10:19:45 | 显示全部楼层 |阅读模式
入门实战-权限管理之整理菜单导航控制显示
这系列的教程最开始就是从一个菜单功能讲起的,最后也在此功能上结束。导航菜单现在都是静态的,在默认的_Layout.cshtml文件中,它的静态代码结构是这样的:
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Manager" asp-action="Index">用户管理</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="ManagerRole" asp-action="Index">角色管理</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Menu" asp-action="Index">菜单管理</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Article" asp-action="Index">文章管理</a>
</li>现在,我通过程序的方式控制代码输出显示,变成动态的结构形式,我采用2种方式实现动态菜单,一个是采用Html.Partial的形式来实现局部视图代码,一个是采用ViewCommpent的形式来实现。
(1).现在导航_Layout.cshtml文件中,导航代码部分做个修改:


Html.PartialAsync()此处调用需要2个参数,一个是局部视图的名称,一个是数据对象;
(2).我们还在Shared文件夹下新建一个视图


_Nav.cshtml代码改为:
@using RjWebCms.Models.Roles;
@model RoleMenuView[]
@if(Model !=null)
{
foreach (var item in Model)
    {
<li class="nav-item">
<a class="nav-link text-dark" asp-action="@item.MenuUrl">@item.MenuName</a>
</li>
        }
}
@*<li class="nav-item">
    <a class="nav-link text-dark" asp-area="" asp-controller="ManagerRole" asp-action="Index">角色管理1</a>
</li>
<li class="nav-item">
    <a class="nav-link text-dark" asp-area="" asp-controller="Menu" asp-action="Index">菜单管理1</a>
</li>
<li class="nav-item">
    <a class="nav-link text-dark" asp-area="" asp-controller="Article" asp-action="Index">文章管理1</a>
</li>*@其实这段代码就是从原来的_Layout.cshtml中拷贝过来的,然后在_Nav.cshtml中需要改成动态输出。
(3). Html.PartialAsync()的第二个参数数据模型是这样生成的
(3.1)在HomeController.cs中的Index的Action中,定义了一个ViewBag数据,当然你改成ViewData也行的通。


(3.2)补充好_rolePermissionService.GetRoleMenus(int.Parse(RoleId));对应的函数,注意,在HomeController中注入RolePermissionService


(3.3).在RolePermissionService.cs中添加一个GetRoleMenus(int roleid)函数,目的就是找出该角色的菜单列表来。


注意,这里为菜单的需要,建了一个RoleMenuView的ModelView对象,物理表RolePermission只是存储2个关键字段,RoleId和MenuId,无法满足我们同时还需要名称,Url等信息。


public class RoleMenuView
    {
public int RoleId { get; set; }
public string RoleName { get; set; }
public int MenuId { get; set; }
public string MenuName { get; set; }
public string MenuUrl { get; set; }
}可以把第三步的过程反过来看,就也能进一步了解导航动态实现的效果。
(4). Component.InvokeAsync()方式,实现动态菜单。
(4.1).第三步中的RoleMenuView类,还有RolePermissionService中的GetRoleMenus()保持不变。
(4.2)在项目根目录中新加一个文件夹:Components,里面新建一个类文件:NavViewCompoent.cs.


代码为(注意:ViewComponent(Name = "Navigation")的声明,Name值就是_Layout中引用的名称):
[ViewComponent(Name = "Navigation")]
public class NavViewCompoent : ViewComponent
    {
private readonly IRolePermissionService _rolePermissionService;
public NavViewCompoent(IRolePermissionService rolePermissionService)
        {
            _rolePermissionService = rolePermissionService;
        }
public IViewComponentResult Invoke()
        {
if (User.Identity.IsAuthenticated)
            {
string RoleId = HttpContext.User.FindFirst(ClaimTypes.Role).Value;//读取用户的Claims信息
var menus = _rolePermissionService.GetRoleMenus(int.Parse(RoleId));
//手动指定了路径的方式,如果是默认:return View(menus);则回自动寻找路径
return View($"~/Views/Shared/Components/Navigation.cshtml", menus);
            }
else
return View($"~/Views/Shared/Components/Navigation.cshtml");
        }
}(4.3).在Views/Shared/文件夹下(注意,如果采用默认路径,需要这样)再建文件夹Navigation,然后在其内建个default.cshtml的视图文件(代码与上面第三步的_Nav.cshtml的代码一样),用来编写像上面第3步中的_Nav.cshtml的导航文件。我是采用手动指定路径的方式,见上面NavViewCompoent的代码中的return view(),我手动指定了返回路径。


否则,就是报错:默认路径不对的错误!


(4.4).在_Layout.cshtml中的代码为:


InvokeAsync()的参数就是[ViewComponent(Name = "Navigation")]的name值。
效果如下:




实现过程的注意事项:

  • 新建了一个专门的ViewModel用来展示导航菜单:RoleMenuView
  • Controller与_Layout.cshtml之间的传值,用了ViewBag,要注意类型的一致性;
  • 如果是列出二级菜单,注意将RoleMenuView中添加一个子菜单集合,参考将下拉框的递归功能代码。
  • 列出的菜单,将系统管理这样的没有Url的都列出了,可以通过linq条件再做次筛选。
关于Partial View(局部视图)和Compoent View(视图组件)的区别,网上有很多信息,百度,bing一下就有很多网友的讲解。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表