1. 程式人生 > >使用依賴注入的ASP.NET Core 2.0使用者角色基礎動態選單管理

使用依賴注入的ASP.NET Core 2.0使用者角色基礎動態選單管理

目錄

介紹

背景

先決條件

使用程式碼

第1步 - 建立資料庫

建立資料庫

第2步 - 建立ASP.NET Core

更新appsettings.json

步驟3 - 在Startup.cs檔案中新增Identity Service

第4步:註冊並建立使用者

重新整理資料庫

第5步:建立角色併為角色分配使用者

第6步:建立Admin/Manager頁面並設定授權

步驟7:使用依賴注入進行選單顯示

建立模型類

建立介面類

建立服務

註冊服務

在_Layout.cshtml頁面中注入服務

興趣點


Download source code - 2.2 MB

介紹

https://www.codeproject.com/KB/aspnet/1237650/ASPDynamicMenu.gif

在開始閱讀本文之前,請仔細閱讀我之前的文章:ASP.NET Core 2.0身份和角色管理入門

在我之前的文章中,我們已經詳細討論瞭如何在MVC應用程式中使用ASP.NET Core Identity來建立使用者角色並根據使用者角色顯示選單。

在本文中,我們將詳細介紹如何在使用者登入後顯示基於角色的動態選單。為此,我們將建立一個Menu Master表並插入一些記錄以顯示選單和連結到URL的選單,這些選單是基於登入使用者的角色的。

在這裡,我們將看到如何實現:

  • 建立預設管理員和經理使用者
  • 建立MenuMaster表並插入一些示例記錄為Admin
    Manager角色以顯示選單
  • 將未經身份驗證的使用者重定向到登入頁面
  • 根據登入使用者動態顯示選單

 

背景

先決條件

確保已在計算機上安裝了所有必備元件。如果沒有,那麼一個接一個地下載並安裝它們。

  1. 首先,從此連結下載並安裝Visual Studio 2017
  2. SQL Server 2014或更高版本

 

使用程式碼

1 - 建立資料庫

這是我們上一篇文章的延續正如我們告訴你的那樣,我們將為ASP.NET Identity表和我們自己的新表使用公共資料庫。

在我們之前的文章中,我們已經解釋瞭如何建立使用者角色,這裡基於角色的選單管理,我們需要在

ASP.NET Roles表和我們的menu表之間建立關係。

讓我們詳細瞭解如何建立Menu表,其於ASP.NET Identity 中的AspNetRoles表是有關係的。

在這裡,我們可以看到用於MenuMaster表的欄位:

https://www.codeproject.com/KB/aspnet/1237650/0.PNG

首先,我們將建立一個數據庫,並使用我們的新資料庫連線,在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'(在這裡,我們會給出使用者角色,如果同樣的選單需要被用於基於像AdminManagerAccountant等等這樣使用者的多個角色,那麼我們將使用不同的使用者角色插入相同的選單的詳細資訊。在我們的示例中,我們為AdminManager使用者添加了與“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。輸入您的專案名稱並單擊。

https://www.codeproject.com/KB/aspnet/1237650/1.PNG

選擇Web Application (Model-View-Controller),然後單擊更改身份驗證

https://www.codeproject.com/KB/aspnet/1237650/2.PNG

選擇個人使用者帳戶,然後單擊確定以建立專案。

https://www.codeproject.com/KB/aspnet/1237650/3.PNG

更新appsettings.json

appsettings.json檔案中,我們可以找到DefaultConnection連線字串。在連線字串中,更改你的SQL Server名稱,UIDPWD以在一個數據庫中建立和儲存所有使用者詳細資訊。

"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應用程式已準備好供使用者在我們的網站上註冊,且使用者也可以在註冊後登入我們的系統。我們將通過在後續步驟中向用戶新增角色來執行授權。構建並執行應用程式以註冊您的第一個預設管理員使用者。

https://www.codeproject.com/KB/aspnet/1237650/4.PNG

在這裡,我們將註冊兩個使用者,一個使用者為Admin而另一個使用者為Manager。我們將使用這些使用者來新增角色。我們將建立2個使用者[email protected][email protected]注意:您可以根據需要建立使用者,並在啟動程式碼中更改使用者詳細資訊,以便向用戶新增角色。

https://www.codeproject.com/KB/aspnet/1237650/5.PNG

重新整理資料庫

重新整理資料庫時,我們可以看到所有Identity表都已建立。

https://www.codeproject.com/KB/aspnet/1237650/6.PNG

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>

https://www.codeproject.com/KB/aspnet/1237650/Animation_1.gif

興趣點

首先,AttendanceDBSQL Server中建立一個示例資料庫,然後執行指令碼來建立MenuMaster表並插入樣本記錄。在appsettings.json檔案中,DefaultConnection使用SQL Server Connections 更改連線字串。在Startup.cs檔案中,新增我們在本文中討論的所有程式碼。這是一個簡單的演示應用程式,我們已經固定了AdminManager角色,你可以根據你的要求進行更改,選單和子選單的CSS設計也不利於移動相容性,你可以新增自己的bootstrap設計來實現你的選單風格。希望大家都喜歡這篇文章。

 

原文地址:https://www.codeproject.com/Articles/1237650/ASP-NET-Core-User-Role-Base-Dynamic-Menu-Managemen