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

  • 篇(19)-Asp.Net Core 入门实战-权限管理之整理菜单导航控制显示(Partial View和Component View)已关闭评论
  • 118 次浏览
  • A+
所属分类:.NET技术
摘要

入门实战-权限管理之整理菜单导航控制显示这系列的教程最开始就是从一个菜单功能讲起的,最后也在此功能上结束。导航菜单现在都是静态的,在默认的_Layout.cshtml文件中,它的静态代码结构是这样的:

入门实战-权限管理之整理菜单导航控制显示

这系列的教程最开始就是从一个菜单功能讲起的,最后也在此功能上结束。导航菜单现在都是静态的,在默认的_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文件中,导航代码部分做个修改:

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

Html.PartialAsync()此处调用需要2个参数,一个是局部视图的名称,一个是数据对象;

(2).我们还在Shared文件夹下新建一个视图

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

_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也行的通。

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

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

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

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

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

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

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

    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.

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

代码为(注意: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(),我手动指定了返回路径。

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

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

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

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

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

InvokeAsync()的参数就是[ViewComponent(Name = "Navigation")]的name值。

效果如下:

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

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

实现过程的注意事项:

  1. 新建了一个专门的ViewModel用来展示导航菜单:RoleMenuView
  2. Controller与_Layout.cshtml之间的传值,用了ViewBag,要注意类型的一致性;
  3. 如果是列出二级菜单,注意将RoleMenuView中添加一个子菜单集合,参考将下拉框的递归功能代码。
  4. 列出的菜单,将系统管理这样的没有Url的都列出了,可以通过linq条件再做次筛选。

关于Partial View(局部视图)和Compoent View(视图组件)的区别,网上有很多信息,百度,bing一下就有很多网友的讲解。