Before you start reading this article, kindly go through my previous article, ASP.NET MVC 5 Security and Creating User Role. It explains in detail about ASP.NET Identity and creating User Role.
Introduction
In this article, we will see how to create and manage a User Role based Menu using ASP.NET MVC, WEB API and AngularJS.
Here, we will see how to do the following:
- Menu management by Admin (Only Admin user can View All / Create / Delete and Edit Menu)
- Create Menu by User Role (Admin can create menu by selecting User Role)
- Show and Hide Dynamic Menu and Sub Menu by User Role
- Dynamically Display Menu by User Role (here, we have mentioned as Dynamic menu as in every page or in Master Page, we will be loading menu from database and display the menu to each user by their role.)
Why We Need to Create a Dynamic Menu
If we are working on a simple web site creation with very few pages and only one programmer is working to create a website, then we can create a static menu and use it in our web site.
Let's now consider that we need to work for a big web application project. Let's consider development of an ERP Web application.
However, if more than two developers are working and perhaps the number of pages is greater than 50 to 100, then it will be hard to maintain a static menu.
And also, there will be a greater chance of removing and adding a new menu item to the web project, for example, our client can ask to add 5 more new menus or remove 1 menu item.
In this case, it will be a hard and difficult task to remove the menu items that are live now.
And also for large web projects like ERP, we need to display the menu depending on the user roles. If we use a static menu, then it will be very difficult to manage the users for the menu.
To avoid all this, we create a Menu Management with a User Role setting.
Who Can Manage the Menu
This is a very important part since an Admin or Superuser can Add/Edit/Delete a Menu.
When an Admin is logged in, he can add a new menu, edit an existing menu and delete a menu item to be displayed.
In this article, we will see in detail how to create a CRUD (Insert
/Update
/Select
and Edit
) Menu by Admin User and display the Admin created Menu to Logged In user by their Role using ASP.NET MVC, WEB API and AngularJS.
You can also view our previous article which explains how to display menu dynamically using MVC, AngularJS and WCF REST Service link.
Prerequisites
Using the Code
Create Database and Table
This is in continuation of our previous article as we have told that we will be using a common database for both ASP.NET Identity tables and for our own new tables.
In our previous article, we have explained about creating User Role and during User registration, user can select their Role.
Here for Role based Menu management, we need to make a relationship table between ASP.NET Roles table and our menu table.
Let us see in detail how to create our new Menu Table which has a relationship with ASP.NET Identity AspNetRoles
table.
Here, we can see Field used for MenuMaster
.
Here, we can see Admin Role user Login and Menu displayed for Admin.
Here, we can see Manager Role user Login and Menu displayed for Manager.
Here, we can see Employee Role user Login and Menu displayed for Employee
.
Menu Master Table and Stored Procedure for Menu CRUD Operation
We will be using our existing database which we used in our previous article, ASP.NET MVC 5 Security and Creating User Role.
The following is the script to create a table, run this script in your SQL Server. I have used SQL Server 2014.
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
After creating our Table
, we will create a Stored Procedure for our CRUD Operations. Firstly, run the following script to create our Stored Procedures. Each procedure has description of its use.
CREATE PROCEDURE [dbo].[USP_UserRoles_Select]
(
@Rolename VARCHAR(30) = ''
)
AS
BEGIN
Select ID,Name
FROM
AspNetRoles
WHERE
Name like @Rolename +'%'
END
CREATE PROCEDURE [dbo].[USP_Menu_Select]
(
@MenuID VARCHAR(30) = '',
@MenuName VARCHAR(30) = ''
)
AS
BEGIN
Select MenuIdentity ,
MenuID ,
MenuName ,
Parent_MenuID ,
User_Roll,
MenuFileName ,
MenuURL ,
USE_YN ,
CreatedDate
FROM
MenuMaster
WHERE
MenuID like @MenuID +'%'
AND MenuName like @MenuName +'%'
ORDER BY
MenuName,MenuID
END
CREATE PROCEDURE [dbo].[USP_MenubyUserRole_Select]
(
@Rolename VARCHAR(30) = ''
)
AS
BEGIN
Select MenuIdentity ,
MenuID ,
MenuName ,
Parent_MenuID ,
User_Roll,
MenuFileName ,
MenuURL ,
USE_YN ,
CreatedDate
FROM
MenuMaster
WHERE
User_Roll = @Rolename
AND USE_YN ='Y'
ORDER BY
MenuName,MenuID
END
CREATE PROCEDURE [dbo].[USP_Menu_Insert]
(
@MenuID VARCHAR(30) = '',
@MenuName VARCHAR(30) = '',
@Parent_MenuID VARCHAR(30) = '',
@User_Roll VARCHAR(200) = '',
@MenuFileName VARCHAR(100) = '',
@MenuURL VARCHAR(500) = '',
@USE_YN VARCHAR(1) = ''
)
AS
BEGIN
IF NOT EXISTS (SELECT * FROM MenuMaster _
WHERE MenuID=@MenuID and MenuName=@MenuName)
BEGIN
INSERT INTO MenuMaster
( MenuID , MenuName , _
Parent_MenuID , User_Roll, MenuFileName ,
MenuURL , USE_YN , CreatedDate )
VALUES ( @MenuID , @MenuName , _
@Parent_MenuID , @User_Roll, @MenuFileName ,
@MenuURL , @USE_YN , GETDATE())
Select 'Inserted' as results
END
ELSE
BEGIN
Select 'Exists' as results
END
END
CREATE PROCEDURE [dbo].[USP_Menu_Update]
( @MenuIdentity Int=0,
@MenuID VARCHAR(30) = '',
@MenuName VARCHAR(30) = '',
@Parent_MenuID VARCHAR(30) = '',
@User_Roll VARCHAR(200) = '',
@MenuFileName VARCHAR(100) = '',
@MenuURL VARCHAR(500) = '',
@USE_YN VARCHAR(1) = ''
)
AS
BEGIN
IF EXISTS (SELECT * FROM MenuMaster WHERE MenuIdentity=@MenuIdentity )
BEGIN
UPDATE MenuMaster SET
MenuID=@MenuID,
MenuName=MenuName,
Parent_MenuID=@Parent_MenuID,
User_Roll=@User_Roll,
MenuFileName=@MenuFileName,
MenuURL=@MenuURL,
USE_YN=@USE_YN
WHERE
MenuIdentity=@MenuIdentity
Select 'updated' as results
END
ELSE
BEGIN
Select 'Not Exists' as results
END
END
Create PROCEDURE [dbo].[USP_Menu_Delete]
( @MenuIdentity Int=0 )
AS
BEGIN
DELETE FROM MenuMaster WHERE MenuIdentity=@MenuIdentity
END
2. Create your MVC Web Application in Visual Studio 2015
As we have mentioned that this is in continues of our previous article. We will be using our existing project, which we used in our previous article you can download the source code.
Click Start, then Programs and select Visual Studio 2015 - Click Visual Studio 2015.
Click Open Project, go to your downloaded project folder and open the solution file.
Add Database using ADO.NET Entity Data Model
Right click our project and click Add, then New Item. Select Data, then ADO.NET Entity Data Model and give the name for our EF and click.
Select "EF Designer from database" and click Next.
Here, we do not need to create a new Connection as we can use the existing connection which we used for our ASP.NET Identity User registration and Login. Click Next to select our Tables and Stored Procedure for Menu management.
Here, we can see newly create MenuMaster
table with existing ASP.NET Identity tables and all newly created stored procedures have been selected for performing our Menu CRUD operations.
Here, we can see now we have created our UsermenuModel
.
Once the Entity has been created, the next step is to add a Web API to our controller and write the function to Select
/Insert
/Update
and Delete
.
Procedure to Add our Web API Controller
Right-click the Controllers folder, click Add and then click Controller.
Select Web API 2 Controller – Empty, click Add and give name for our WEB API controller.
Note: Here, we are using our existing MVC project and we didn’t create the MVC Project with option selected as WEB API. So when we add a WEB API controller, we can see the following readme text.
For using WEB API for non-WEB API MVC project, we need to add the above mentioned reference and Config like below in Global.asax file.
When we open Global.asax file, we can see the System.Web.Http
reference was missing and also GlobalConfiguration
was not been added in Application_Start
.
Here, we add the reference and GlobalConfiguration
like below to use WEB API.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Http;
namespace shanuMVCUserRoles
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
In App_Start
, WebApiConfig.cs change the routeTemplate
like below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace shanuMVCUserRoles
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Working with WEBAPI Controller for CRUD
Select Controller and add an Empty Web API 2 Controller. Provide your name to the Web API controller and click OK. Here for my Web API Controller, I have given the name MenuAPIController
.
As we have created Web API controller, we can see our controller has been inherited with ApiController
.
As we all know, Web API is a simple and easy way to build HTTP Services for Browsers and Mobiles.
Web API has the following four methods as Get
/Post
/Put
and Delete
where:
Get
is to request for the data. (Select
) Post
is to create a data. (Insert
) Put
is to update the data. Delete
is to delete data.
Get Method
In our example, I have used only a Get
method since I am using only a Stored Procedure. We need to create an object for our Entity and write our Get
Method to do Select
/Insert
/Update
and Delete
operations.
Select Operation
We use a get
method to get all the details of the MenuMasters
table using an entity object and we return the result as IEnumerable
. We use this method in our AngularJS and display the result in an MVC page from the AngularJS controller. Using Ng-Repeat
, we can bind the details.
Here, we can see in the getMenuCRUDSelect
method, I have passed the search parameter to the USP_Menu_Select
Stored Procedure. In the Stored Procedure, I used like "%
" to return all the records if the search parameter is empty.
[HttpGet]
public IEnumerable<USP_Menu_Select_Result>
getMenuCRUDSelect(string menuID, string menuName)
{
if (menuID == null)
menuID = "";
if (menuName == null)
menuName = "";
return objapi.USP_Menu_Select(menuID, menuName).AsEnumerable();
}
We have created one more select
method to get all User Role to bind in ComboBox
in our MVC view using AngularJS.
[HttpGet]
public IEnumerable<USP_UserRoles_Select_Result> getUserRoleDetails(string UserRole)
{
if (UserRole == null)
UserRole = "";
return objapi.USP_UserRoles_Select(UserRole).AsEnumerable();
}
Next we have one more Select
method. This method will be used to display menu for each user by their logged in role.
[HttpGet]
public IEnumerable<USP_MenubyUserRole_Select_Result> getMenubyUserRole(string UserRole)
{
if (UserRole == null)
UserRole = "";
return objapi.USP_MenubyUserRole_Select(UserRole).AsEnumerable();
}
Here in our example, we have used the get
method for Select
/Insert
/Update
and Delete
operations, since in my Stored Procedure after insert
/update
and delete
, I have returned the message from the database.
Insert Operation
Similar to select
, we passed all the parameters to the insert
procedure. This insert
method will return the result from the database as a record is inserted or not. We will get the result and display it from the AngularJS Controller to MVC application.
[HttpGet]
public IEnumerable<string> insertMenu(string menuID, string menuName,
string parentMenuID, string UserRole,
string menuFileName, string MenuURL, string UseYN)
{
return objapi.USP_Menu_Insert(menuID, menuName, parentMenuID,
UserRole, menuFileName, MenuURL, UseYN).AsEnumerable();
}
Update Operation
Just like Insert
, we have passed all the parameters to the Update
procedure. This Update
method will return the result from the database as a record is updated or not.
[HttpGet]
public IEnumerable<string> updateMenu(int MenuIdentity,
string menuID, string menuName, string parentMenuID,
string UserRole, string menuFileName, string MenuURL, string UseYN)
{
return objapi.USP_Menu_Update(MenuIdentity, menuID, menuName,
parentMenuID, UserRole, menuFileName, MenuURL, UseYN).AsEnumerable();
}
Delete Operation
The same as Insert
, we have passed all the parameters to the Delete
procedure. This Delete
method will return the result from the database as a record is delete or not.
[HttpGet]
public string deleteMenu(int MenuIdentity)
{
objapi.USP_Menu_Delete(MenuIdentity);
objapi.SaveChanges();
return "deleted";
}
Creating AngularJS Controller
Firstly, create a folder inside the Scripts folder and we have given the folder name “MyAngular”.
Now add your Angular Controller inside the folder.
Right click the MyAngular folder and click Add and New Item. Select Web and then AngularJS Controller and provide a name for the Controller. I have named my AngularJS Controller “Controller.js”.
Once the AngularJS Controller is created, we can see by default the controller will have the code with the default module definition and all.
If the AngularJS package is missing, then add the package to your project.
Right click your MVC project and click Manage NuGet Packages. Search for AngularJS and click Install.
Procedure to Create AngularJS Script Files for Menu CRUD
Modules.js: Here, we will add the reference to the:
var app;
(function () {
app = angular.module("RESTClientModule", ['ngAnimate']);
})();
Controllers: In AngularJS Controller, I have done all the business logic and returned the data from Web API to our MVC HTML page.
Variable Declarations
Firstly, we declared all the local variables need to be used.
app.controller("AngularJs_Controller",
function ($scope, $timeout, $rootScope, $window, $http) {
$scope.date = new Date();
$scope.MyName = "shanu";
$scope.sMenuID = "";
$scope.sMenuName = "";
$scope.showMenuAdd = true;
$scope.addEditMenu = false;
$scope.MenuList = true;
$scope.showItem = true;
$scope.userRoleName = $("#txtuserRoleName").val();
$scope.MenuIdentitys = 0;
$scope.menuIDs = "";
$scope.menuNames = "";
$scope.parentMenuIDs = "";
$scope.selectedUserRole = "";
$scope.menuFileNames = "";
$scope.MenuURLs = "";
$scope.UseYNs = true;
$scope.searchRoleName = "";
2. Methods
Select Method
In the select
method, I have used $http.get
to get the details from Web API. In the get
method, I will provide our API Controller name and method to get the details. Here, we can see I have passed the search parameter of OrderNO
and TableID
using:
{ params: { menuID: menuID, menuName: menuName }
The final result will be displayed to the MVC HTML page using data-ng-repeat.
select MenuDetails($scope.sMenuID, $scope.sMenuName);
function selectMenuDetails(menuID, menuName) {
$http.get('/api/MenuAPI/getMenuCRUDSelect/',
{ params: { menuID: menuID, menuName: menuName } }).success(function (data) {
$scope.MenuData = data;
$scope.showMenuAdd = true;
$scope.addEditMenu = false;
$scope.MenuList = true;
$scope.showItem = true;
if ($scope.MenuData.length > 0) {
}
})
.error(function () {
$scope.error = "An Error has occurred while loading posts!";
});
$http.get('/api/MenuAPI/getMenuCRUDSelect/',
{ params: { menuID: "", menuName: "" } }).success(function (data) {
$scope.MenuDataSelect = data;
})
.error(function () {
$scope.error = "An Error has occurred while loading posts!";
});
}
$scope.searchMenuDetails = function () {
selectMenuDetails($scope.sMenuID, $scope.sMenuName);
}
Search Button Click
<table style="color:#9F000F;font-size:large"
cellpadding="4" cellspacing="6">
<tr>
<td>
<b>Menu ID</b>
</td>
<td>
: <input type="text" name="txtMenuID"
ng-model="sMenuID" value="" />
<br />
</td>
<td>
<b> Menu Name </b>
</td>
<td>
:
<input type="text" name="txtMenuName"
ng-model="sMenuName" />
</td>
<td>
<input type="submit" value="Search"
style="background-color:#336699;color:#FFFFFF"
ng-click="searchMenuDetails()" />
</td>
</tr>
</table>
Insert New Menu Master
In the ADD/Edit menu Details button click, we will make visible the MenuAdd
table details where the Admin user can enter the new menu information. For a new Menu, we will make the Menu ID as 0
. In the New Menu save button click, we will call the save
method.
$scope.showMenuAddDetails = function () {
cleardetails();
$scope.showMenuAdd = true;
$scope.addEditMenu = true;
$scope.MenuList = true;
$scope.showItem = true;
}
User Roles Bind to Combobox
For creating new menu, Admin needs to select User Role. For this, we will bind all the ASP.NET Roles table all role details to the combobox
.
AngularJS Controller Part
Using our WebAPI, we get all the User Roles and store the result in $scope.userRoleData
.
select userRoleDetails($scope.searchRoleName);
function selectuerRoleDetails(UserRole) {
$http.get('/api/MenuAPI/getUserRoleDetails/',
{ params: { UserRole: UserRole } }).success(function (data) {
$scope.userRoleData = data;
})
rror(function () {
$scope.error = "An Error has occurred while loading posts!";
}
HTML Part to Bind Combobox with User Roles
<select name="opSelect" id="opSelect" ng-model="selectedUserRole">
<option value="" selected>-- Select --</option>
<option ng-repeat="option in userRoleData"
value="{{option.Name}}">{{option.Name}}</option>
</select>
Parent Menu ID bind to Combobox
For creating sub menu, admin can select parent menu from ComboBox
. Every time when admin creates a Menu, the main menu ID will be added to this combobox
for creating sub menu.
AngularJS Controller Part
Using our WebAPI, we get all the User Roles and store the result in $scope.userRoleData
.
HTML Part to Bind Combobox with Parent Menu ID
<select name="opSelect" id="opSelect" ng-model="parentMenuIDs">
<option value="*" selected>*</option>
<option ng-repeat="option in MenuDataSelect"
value="{{option.MenuID}}">{{option.MenuID}}</option>
</select>
In the Save
method, I will check for the MenuIdentity
. If the MenuIdentitys
is “0
”, then it will insert the new Menu Master. Here, we will call the Insert Web API method and if the MenuIdentitys
is > 0
, then it means to update the Menu record then we will call the Update Web API method.
$scope.saveDetails = function () {
if ($scope.selectedUserRole == "")
{
alert("Select User Role");
return;
}
if ($scope.parentMenuIDs == "") {
alert("Select parent ID");
return;
}
$scope.IsFormSubmitted = true;
if ($scope.IsFormValid) {
if ($scope.UseYNs == true)
{
$scope.UseYNsN = "Y";
}
else
{
$scope.UseYNsN = "N";
}
if ($scope.MenuIdentitys == 0) {
$http.get('/api/MenuAPI/insertMenu/', { params:
{ menuID: $scope.menuIDs, menuName: $scope.menuNames,
parentMenuID: $scope.parentMenuIDs, UserRole: $scope.selectedUserRole,
menuFileName: $scope.menuFileNames, MenuURL: $scope.MenuURLs,
UseYN: $scope.UseYNsN } }).success(function (data) {
$scope.menuInserted = data;
alert($scope.menuInserted);
cleardetails();
selectMenuDetails('', '');
selectMenubyUserRoleDetails($scope.userRoleName);
})
.error(function () {
$scope.error = "An Error has occurred while loading posts!";
});
}
else {
$http.get('/api/MenuAPI/updateMenu/', { params:
{ MenuIdentity: $scope.MenuIdentitys, menuID: $scope.menuIDs,
menuName: $scope.menuNames, parentMenuID: $scope.parentMenuIDs,
UserRole: $scope.selectedUserRole, menuFileName: $scope.menuFileNames,
MenuURL: $scope.MenuURLs, UseYN: $scope.UseYNsN } }).success(function (data) {
$scope.menuUpdated = data;
alert($scope.menuUpdated);
cleardetails();
selectMenuDetails('', '');
selectMenubyUserRoleDetails($scope.userRoleName);
})
.error(function () {
$scope.error = "An Error has occurred while loading posts!";
});
}
}
else {
$scope.Message = "All the fields are required.";
}
$scope.IsFormSubmitted = false;
}
Firstly, we check admin has selected user role and ParentMenuID
for create new menu. Then we check for menu visible to user is checked or not. If it is checked, then we insert status with ‘Y
’ else ‘N
’. For displaying menu, we select the menu visible status is only for ‘Y
’. To Insert Web API Method, we will pass all the Input parameters. In our Stored Procedure, we will check whether the Menu ID for the Menu already exists. If the Menu ID does not exist in the database, then we will insert the records and return the success message as “inserted” and if the Menu ID already exists, then we will return the message as “Exists”.
Here, we can see admin has created new Menu and selected User role for new menu as Employee
and parentMenuID
as ‘*
’ which means this newly created will only be visible to Employee Role users not even to Admin and Parent menu ID as ‘*
’ which is for displaying the menu as root menu Item. Here, we have given the controller name as ‘Message
’. Now we will create one new Controller as “message
” and add a default index view for that controller with simple message display.
Let us login to our MVC application as Employee
user and see how the new created menu is displayed.
Update Menu Master
Here again, we logged in as Admin user for editing the newly created menu. Now we can see we can click on edit icon to edit the selected menu details. Now we will change the parent MenuID
from ‘*
’ to display the menu as sub menu of Employee
Dashboard.
Now again, we login as Employee
user and check for how the menu will be displayed as sub menu.
Update Menu Display Status
Now let’s see how to update the menu not to be visible for user. We login as Admin User and edit the Menu and uncheck the Menu Visible (Yes/No) checkbox and click Save.
If Employee
user logged in this Menu Visible set to ‘N
’ menu will not be displayed to him. Here, we can see Employee
role user is login and he/she can view only one menu and previously displayed “message” menu is not being displaying now.
Delete Order Master Details
In the Delete button click, we will display the confirmation message to the user whether to delete the menu or not. If the user clicks the OK button, we will pass the menuID
to the delete
method of the Web API to delete the record from the database.
$scope.MenuDelete = function MenuDelete(MenuIdentity, menuName) {
cleardetails();
$scope.MenuIdentitys = MenuIdentity;
var delConfirm = confirm
("Are you sure you want to delete the Student " + menuName + " ?");
if (delConfirm == true) {
$http.get('/api/MenuAPI/deleteMenu/',
{ params: { MenuIdentity: $scope.MenuIdentitys } }).success(function (data) {
alert("Menu Deleted Successfully!!");
cleardetails();
selectMenuDetails('', '');
})
.error(function () {
$scope.error = "An Error has occurred while loading posts!";
});
}
}
Display Menu by User Role
For display menu by user role, we will pass the logged in user role to webAPI
method to get all menu details for logged in user role users. In AngularJS controller, we will get the logged in user role from hidden field and in our MVC page, we will bind the logged in User role to hidden
field.
<input type="hidden" id="txtuserRoleName"
value="@ViewBag.UserRole" />
We get this hidden
field value in our AngularJS controller and pass the user role to get all menu for logged in user roles.
$scope.userRoleName = $("#txtuserRoleName").val();
selectMenubyUserRoleDetails($scope.userRoleName);
function selectMenubyUserRoleDetails(UserRole) {
$http.get('/api/MenuAPI/getMenubyUserRole/',
{ params: { UserRole: $scope.userRoleName } }).success(function (data) {
$scope.generateMenuData = data;
})
.error(function () {
$scope.error = "An Error has occurred while loading posts!";
});
}
$scope.showDetails = false;
$scope.showSubDetails = false;
$scope.subChildIDS = "";
$scope.Imagename = "R1.png";
$scope.showsubMenu = function (showMenus, ids) {
if (showMenus == 1) {
$scope.subChildIDS = ids;
$scope.showSubDetails = true;
}
else if (showMenus == 0) {
$scope.showSubDetails = false;
}
else {
$scope.showSubDetails = true;
}
}
In our view page, we bind the menu result to table to display all menu and sub menu like below:
<div style="overflow:visible;height:100px;">
<ul class="menu">
<li data-ng-repeat="menus in generateMenuData |
filter:{Parent_MenuID:'*'}">
@{var url = Url.Action("{{menus.MenuFileName}}",
"{{menus.MenuURL}}", new { id = "{{id=menus.MenuURL}}" });
url = HttpUtility.UrlDecode(url);
}
<a data-ng-href="@url">{{menus.MenuName}}</a>
<ul class="sub-menu">
<li data-ng-repeat="submenus in generateMenuData |
filter:{Parent_MenuID:menus.MenuID}"
ng-mouseover="showsubMenu(1,submenus.MenuID);"
ng-mouseout="showsubMenu(0,submenus.MenuID);">
@{var url1 = Url.Action("{{submenus.MenuFileName}}",
"{{submenus.MenuURL}}",
new { id = "{{id=submenus.MenuURL}}" });
url1 = HttpUtility.UrlDecode(url1);
}
<a data-ng-href="@url1">{{submenus.MenuName}}</a>
<ul ng-show="showSubDetails"
class="sub-menu2">
<li data-ng-repeat="sub1menus in generateMenuData |
filter:{Parent_MenuID:submenus.MenuID}"
ng-mouseover="showsubMenu(3,9);">
@{var url2 = Url.Action("{{sub1menus.MenuFileName}}",
"{{sub1menus.MenuURL}}",
new { id = "{{id=sub1menus.MenuURL}}" });
url2 = HttpUtility.UrlDecode(url2);
}
<a data-ng-href="@url2">{{sub1menus.MenuName}}</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
MVC Controller
In MVC Controller, we check for Authentication and Authorization. Only logged in user can view this page and in controller, we check for each user role and pass the role from Controller to View to display the menu by user role.
public string RoleName { get; set; }
public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
var user = User.Identity;
ViewBag.Name = user.Name;
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>
(new UserStore<ApplicationUser>(context));
var s = UserManager.GetRoles(user.GetUserId());
RoleName = s[0].ToString();
ViewBag.displayMenu = "No";
ViewBag.UserRole = RoleName;
if (RoleName == "Admin")
{
ViewBag.displayMenu = "Yes";
}
return View();
}
else
{
return RedirectToAction("Index", "Home");
}
}
Points of Interest
Firstly, run all the script to your SQL Server. You can also find the SQL Script file from the attached zip file. After you download the source code, kindly change the Web.Config file DefaultConnection
connection string with your SQL Server Connections. In Startup.cs file, we have created default Admin user with UserName
"shanu
" and password
"A@Z200711
". This UserName
and password
will be used to login as Admin user. You can change this user name and password as you like. For security reasons after logging in as Admin, you can change the Admin user password as you like.
History
- 2nd February, 2016: Initial version