入門實戰-權限管理之整理選單導航控制顯示
這系列的教程最開始就是從一個選單功能講起的,最后也在此功能上結束,導航選單現在都是靜態的,在默認的_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一下就有很多網友的講解,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/538089.html
標籤:.NET Core
