使用依賴注入的ASP.NET Core 2.0使用者角色基礎動態選單管理
目錄
步驟3 - 在Startup.cs檔案中新增Identity Service
介紹
在開始閱讀本文之前,請仔細閱讀我之前的文章:ASP.NET Core 2.0身份和角色管理入門。
在我之前的文章中,我們已經詳細討論瞭如何在MVC應用程式中使用ASP.NET Core Identity來建立使用者角色並根據使用者角色顯示選單。
在本文中,我們將詳細介紹如何在使用者登入後顯示基於角色的動態選單。為此,我們將建立一個Menu Master表並插入一些記錄以顯示選單和連結到URL的選單,這些選單是基於登入使用者的角色的。
在這裡,我們將看到如何實現:
- 建立預設管理員和經理使用者
- 建立MenuMaster表並插入一些示例記錄為Admin
- 將未經身份驗證的使用者重定向到登入頁面
- 根據登入使用者動態顯示選單
背景
先決條件
確保已在計算機上安裝了所有必備元件。如果沒有,那麼一個接一個地下載並安裝它們。
- 首先,從此連結下載並安裝Visual Studio 2017
- SQL Server 2014或更高版本
使用程式碼
第1步 - 建立資料庫
這是我們上一篇文章的延續; 正如我們告訴你的那樣,我們將為ASP.NET Identity表和我們自己的新表使用公共資料庫。
在我們之前的文章中,我們已經解釋瞭如何建立使用者角色,這裡基於角色的選單管理,我們需要在
讓我們詳細瞭解如何建立Menu表,其於ASP.NET Identity 中的AspNetRoles表是有關係的。
在這裡,我們可以看到用於MenuMaster表的欄位:
首先,我們將建立一個數據庫,並使用我們的新資料庫連線,在appsettings.json檔案中設定連線字串DefaultConnection。我們將使用此資料庫建立ASP.NET Core Identity表。
建立資料庫
執行以下指令碼以建立資料庫MenuMaster表和示例Menu插入行指令碼。
USE MASTER
GO
-- 1) Check for the Database Exists. If the database exists, then drop and create new DB
IF EXISTS (SELECT [name] FROM sys.databases WHERE [name] = 'AttendanceDB' )
DROP DATABASE AttendanceDB;
GO
CREATE DATABASE AttendanceDB;
GO
USE AttendanceDB
GO
IF EXISTS ( SELECT [name] FROM sys.tables WHERE [name] = 'MenuMaster' )
DROP TABLE MenuMaster;
GO
CREATE TABLE MenuMaster
(
MenuIdentity int identity(1,1),
MenuID VARCHAR(30) NOT NULL,
MenuName VARCHAR(30) NOT NULL,
Parent_MenuID VARCHAR(30) NOT NULL,
User_Roll [varchar](256) NOT NULL,
MenuFileName VARCHAR(100) NOT NULL,
MenuURL VARCHAR(500) NOT NULL,
USE_YN Char(1) DEFAULT 'Y',
CreatedDate datetime
CONSTRAINT [PK_MenuMaster] PRIMARY KEY CLUSTERED
(
[MenuIdentity] ASC,
[MenuID] ASC,
[MenuName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
select * from MenuMaster
-- Insert Admin User Details
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('AUSER','ADMIN Dashboard','*','ADMIN','INDEX','ADMINC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('AAbout','About Admin','*','ADMIN','INDEX','ADMINAC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('LStock','Live Stock','AUSER','ADMIN','INDEX','StockC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('Profile','User Details','AUSER','ADMIN','INDEX','MemberC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('MUSER','Manager Dashboard','*','ADMIN','INDEX','ManagerC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('MAbout','About Manager','*','ADMIN','INDEX','ManagerAC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('Accounts','Account Details','MUSER','ADMIN','INDEX','AccountC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,
MenuURL,USE_YN,CreatedDate)
Values('Inventory','Inventory Details','MUSER','ADMIN','INDEX','InventoryC','Y',getDate())
-- Insert Manager User Details
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('MUSER','Manager Dashboard','*','Manager','INDEX','ManagerC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('MAbout','About Manager','*','Manager','INDEX','ManagerAC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('Accounts','Account Details','MUSER','Manager','INDEX','AccountC','Y',getDate())
Insert into MenuMaster(MenuID ,MenuName,Parent_MenuID,User_Roll,MenuFileName,MenuURL,USE_YN,CreatedDate)
Values('Inventory','Inventory Details','MUSER','Manager','INDEX','InventoryC','Y',getDate())
select * from MenuMaster;
select * from AspnetUserRoles;
在這裡,我們可以在Menu Master表中看到我們使用的格式,以根據使用者角色插入顯示選單的記錄。
- MenuID = 'AUSER' (我們將提供獨特的選單ID)。
- MenuName = 'ADMIN Dashboard' (我們將提供選單顯示文字),
- Parent_MenuID = '*’(如果這是主選單,那麼我們將在此處給出“ *”,否則我們將給出之前的記錄MenuID以顯示此記錄以顯示為子選單)。
- User_Roll = 'ADMIN'(在這裡,我們會給出使用者角色,如果同樣的選單需要被用於基於像Admin,Manager,Accountant等等這樣使用者的多個角色,那麼我們將使用不同的使用者角色插入相同的選單的詳細資訊。在我們的示例中,我們為Admin和Manager使用者添加了與“Manager Dashboard”相同的選單細節,因為兩者都可以檢視選單和頁面。)。
- MenuFileName = 'INDEX'(這裡,在單擊選單時顯示我們給出的View名字)。
- MenuURL = 'ADMINC'(這裡,在單擊選單時顯示我們給出的Controller名字)。
- USE_YN = 'Y' (這是一個可選欄位,因為我們可以使用它來顯示選單或不顯示)。
- CreatedDate = getDate() (這也是輸入建立日期的可選項)。
在此演示應用程式中,當用戶單擊選單時,我們已經有了所有需要的控制器和檢視。
第2步 - 建立ASP.NET Core
安裝我們的Visual Studio 2017後,單擊開始,然後單擊程式並選擇Visual Studio 2017——單擊Visual Studio 2017。單擊新建,然後單擊專案,選擇Web,然後選擇ASP.NET Core Web Application。輸入您的專案名稱並單擊。
選擇Web Application (Model-View-Controller),然後單擊“更改身份驗證”。
選擇個人使用者帳戶,然後單擊確定以建立專案。
更新appsettings.json
在appsettings.json檔案中,我們可以找到DefaultConnection連線字串。在連線字串中,更改你的SQL Server名稱,UID和PWD以在一個數據庫中建立和儲存所有使用者詳細資訊。
"ConnectionStrings": {
"DefaultConnection": "Server= YOURSERVERNAME;Database=InventoryDB;
user id= YOURSQLUSERID;password=YOURSQLPASSWORD;Trusted_Connection=True;
MultipleActiveResultSets=true"
},
步驟3 - 在Startup.cs檔案中新增Identity Service
預設情況下,在ASP.NET Core應用程式中,Identity Service將新增到Startup.cs檔案中的 ConfigureServices方法中。您還可以在使用者註冊時另外新增密碼強度,還可以使用以下程式碼設定預設登入頁/登出頁以及AccessDenaiedPath:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
//Password Strength Setting
services.Configure<IdentityOptions>(options =>
{
// Password settings
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = false;
options.Password.RequiredUniqueChars = 6;
// Lockout settings
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
options.Lockout.MaxFailedAccessAttempts = 10;
options.Lockout.AllowedForNewUsers = true;
// User settings
options.User.RequireUniqueEmail = true;
});
//Setting the Account Login page
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.LoginPath = "/Account/Login"; // If the LoginPath is not set here,
// ASP.NET Core will default to /Account/Login
options.LogoutPath = "/Account/Logout"; // If the LogoutPath is not set here,
// ASP.NET Core will default to /Account/Logout
options.AccessDeniedPath = "/Account/AccessDenied"; // If the AccessDeniedPath
// is not set here, ASP.NET Core will default to /Account/AccessDenied
options.SlidingExpiration = true;
});
第4步:註冊並建立使用者
現在,我們的ASP.NET Core Web應用程式已準備好供使用者在我們的網站上註冊,且使用者也可以在註冊後登入我們的系統。我們將通過在後續步驟中向用戶新增角色來執行授權。構建並執行應用程式以註冊您的第一個預設管理員使用者。
在這裡,我們將註冊兩個使用者,一個使用者為Admin而另一個使用者為Manager。我們將使用這些使用者來新增角色。我們將建立2個使用者[email protected]和[email protected]。注意:您可以根據需要建立使用者,並在啟動程式碼中更改使用者詳細資訊,以便向用戶新增角色。
重新整理資料庫
重新整理資料庫時,我們可以看到所有Identity表都已建立。
第5步:建立角色併為角色分配使用者
我們使用以下方法建立一個新角色“ Admin”和“ Manager”。我們會將最近註冊的使用者分配為“ Admin”和“ Manager”到我們的網站。開啟Startup.cs檔案,並在你的Startup.cs檔案中新增此方法。
private async Task CreateUserRoles(IServiceProvider serviceProvider)
{
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
IdentityResult roleResult;
//Adding Addmin Role
var roleCheck = await RoleManager.RoleExistsAsync("Admin");
if (!roleCheck)
{
//create the roles and seed them to the database
roleResult = await RoleManager.CreateAsync(new IdentityRole("Admin"));
}
roleCheck = await RoleManager.RoleExistsAsync("Manager");
if (!roleCheck)
{
//create the roles and seed them to the database
roleResult = await RoleManager.CreateAsync(new IdentityRole("Manager"));
}
//Assign Admin role to the main User here we have given our
//newly loregistered login id for Admin management
ApplicationUser user = await UserManager.FindByEmailAsync("[email protected]");
var User = new ApplicationUser();
await UserManager.AddToRoleAsync(user, "Admin");
user = await UserManager.FindByEmailAsync("[email protected]");
await UserManager.AddToRoleAsync(user, "Manager");
}
從Startup.cs檔案中,我們可以找到該Configure方法。從這個Configure方法中呼叫我們的CreateUserRoles方法。當我們構建並執行我們的應用程式時,我們可以看到在ASPNetRole表中新的角色為“ Admin”和“ Manager”將建立。
第6步:建立Admin/Manager頁面並設定授權
現在我們為ASP.NET Core Web應用程式提供了一個Admin / Manager使用者作為下一步,讓我們建立基於使用者登入顯示的控制器和檢視。在前面的示例中,我們已經瞭解瞭如何在每個頁面中設定角色授權,使用它,我們將建立所有需要的控制器和檢視。在附帶的示例演示應用程式中,您可以找到我們建立的所有控制器和檢視,並根據您的需要建立自己的控制器和檢視。
步驟7:使用依賴注入進行選單顯示
建立模型類
首先,我們將從Model資料夾中建立一個類開始。我們建立一個名為的MenuMaster類,其和資料庫中給出表名是完全相同的。在MenuMaster類中,我們需要建立和Table欄位一樣名稱的屬性,如下:
public class MenuMaster
{
[Key]
public int MenuIdentity { get; set; }
public string MenuID { get; set; }
public string MenuName { get; set; }
public string Parent_MenuID { get; set; }
public string User_Roll { get; set; }
public string MenuFileName { get; set; }
public string MenuURL { get; set; }
public string USE_YN { get; set; }
public DateTime CreatedDate { get; set; }
}
建立介面類
現在,我們是時候建立一個帶有名稱為GetMenuMaster(),GetMenuMaster(String UserRole)的方法的介面,我們將在我們的服務中實現這個介面,以從表中獲取所有選單細節,並且還使用另一個方法來根據使用者角色獲取選單。要建立介面,請在model資料夾中新增一個新類,並將該類命名為“ IMenuMasterService”。
我們將把類更改為介面,因為我們將建立要在服務中實現的介面。
public interface IMenuMasterService
{
IEnumerable<MenuMaster> GetMenuMaster();
IEnumerable<MenuMaster> GetMenuMaster(String UserRole);
}
建立服務
現在,讓我們新增一個新的Services類資料夾,並將該類命名為“ MenuMasterService”。在這個類中,我們將實現我們的介面 IMenuMasterService。我們知道如果我們實現了介面,那麼我們應該在我們的類中宣告該介面方法。在此服務中,我們使用該介面方法,並返回包含Menu詳細資訊的列表,和按使用者角色返回的Menu詳細資訊。我們將直接在View頁面上注入此內容。
public class MenuMasterService:IMenuMasterService
{
private readonly ApplicationDbContext _dbContext;
public MenuMasterService(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
public IEnumerable<MenuMaster> GetMenuMaster()
{
return _dbContext.MenuMaster.AsEnumerable();
}
public IEnumerable<MenuMaster> GetMenuMaster(string UserRole)
{
var result = _dbContext.MenuMaster.Where(m => m.User_Roll == UserRole).ToList();
return result;
}
}
註冊服務
我們需要將我們建立的服務註冊到容器中。從專案中開啟Startup.cs以將服務新增到容器中。
在Startup.cs類中,找到名為ConfigureServices的方法並新增您的服務“ MenuMasterService”,如下所示:
services.AddTransient<MenuMasterService, MenuMasterService>();
在_Layout.cshtml頁面中注入服務
現在,它更加簡單和容易,因為我們可以直接在View頁面中注入服務並將所有結果繫結到我們的檢視頁面。要在我們的View中注入服務,這裡我們將使用現有的_Layout.cshtml頁面。由於我們將在我們網站的頂部顯示選單並在我們的所有頁面中使用,因此我們使用_Layout.cshtml頁面將選單結果繫結為基於使用者登入的選單。
在這裡,首先我們檢查使用者是否已通過我們的網站驗證,然後如果使用者已登入,則我們獲取登入使用者的角色詳細資訊並根據使用者角色繫結選單。在這裡,我們將2級選單繫結為主選單和子選單。在我們的表結果中,我們檢查所有的Parent_MenuID=” *” ,因為我們將帶有parent_MenuID是“ *” 的顯示為主選單,在下一個內迴圈中,我們顯示對應主選單的子選單。
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
@if (User.Identity.IsAuthenticated)
{
var UserRoles = "";
if (@User.IsInRole("Admin"))
{
UserRoles = "Admin";
}
else
{
UserRoles = "Manager";
}
@if (menus.GetMenuMaster(@UserRoles).Any())
{
@if (menus.GetMenuMaster(@UserRoles).Any())
{
@foreach (var menuNames in menus.GetMenuMaster(@UserRoles).Where
(n => n.Parent_MenuID == "*"))
{
<li>
<a asp-area="" [email protected]
[email protected]>@menuNames.MenuName</a>
<ul class="sub-menu">
@foreach (var subMenu in menus.GetMenuMaster(@UserRoles).Where
(n => n.Parent_MenuID == @menuNames.MenuID))
{
<li>
<a asp-area="" [email protected]
[email protected]>@subMenu.MenuName</a>
</li>
}
</ul>
</li>
}
}
}
}
</ul>
興趣點
首先,AttendanceDB在SQL Server中建立一個示例資料庫,然後執行指令碼來建立MenuMaster表並插入樣本記錄。在appsettings.json檔案中,DefaultConnection使用SQL Server Connections 更改連線字串。在Startup.cs檔案中,新增我們在本文中討論的所有程式碼。這是一個簡單的演示應用程式,我們已經固定了Admin和Manager角色,你可以根據你的要求進行更改,選單和子選單的CSS設計也不利於移動相容性,你可以新增自己的bootstrap設計來實現你的選單風格。希望大家都喜歡這篇文章。
原文地址:https://www.codeproject.com/Articles/1237650/ASP-NET-Core-User-Role-Base-Dynamic-Menu-Managemen