ASP.NET MVC User Role Base Menu Management Using WEB API And AngularJS

In this article we will see how to create and manage a User Role based menu using ASP.NET MVC, WEB API and AngularJS.

Before starting 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

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,

  1. Menu management by Admin (Only Admin user can View All / Create /Delete and Edit Menu).
  2. Create Menu by User Role (Admin can create menu by selecting User Role)
  3. Show and Hide Dynamic Menu and Sub Menu by User Role
  4. 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 data base 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 in that case we can create a static menu and use it in our web site.

Let's now consider 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 Super user 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

Visual Studio 2015: You can download it from here.

Code part

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 base Menu management we need to make a relationship table between ASP.NET Roles table and our menu table.

Let us see in detail about how to create our new Menu Table which has 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 (link above).

The following is the script to create a table, run this script in your SQL Server. I have used SQL Server 2014. 

  1. USE AttendanceDB    
  2. GO    
  3.   
  4. IF EXISTS ( SELECT [nameFROM sys.tables WHERE [name] = 'MenuMaster' )    
  5. DROP TABLE MenuMaster    
  6. GO    
  7.     
  8. CREATE TABLE MenuMaster    
  9. (    
  10.    MenuIdentity int identity(1,1),    
  11.    MenuID VARCHAR(30)  NOT NULL,    
  12.    MenuName VARCHAR(30)  NOT NULL,  
  13.    Parent_MenuID  VARCHAR(30)  NOT NULL,  
  14.    User_Roll [varchar](256) NOT NULL,   
  15.    MenuFileName VARCHAR(100) NOT NULL,     
  16.    MenuURL VARCHAR(500) NOT NULL,    
  17.    USE_YN Char(1) DEFAULT 'Y',    
  18.    CreatedDate datetime    
  19. CONSTRAINT [PK_MenuMaster] PRIMARY KEY CLUSTERED          
  20. (         
  21.   [MenuIdentity] ASC   ,    
  22.   [MenuID] ASC,    
  23.   [MenuName] ASC      
  24. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]         
  25. ON [PRIMARY]       
  26.   
  27. 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. 
  1. -- 1) Stored procedure To Select all user roles   
  2.   
  3. -- Author      : Shanu                                                                  
  4. -- Create date : 2016-01-30                                                                 
  5. -- Description :select all AspNetRoles   all roll name to display in Combobox for menu creation.                                              
  6. -- Tables used :  AspNetRoles                                                              
  7. -- Modifier    : Shanu                                                                  
  8. -- Modify date : 2016-01-30                                                                  
  9. -- =============================================    
  10. -- To Select all user roles   
  11. -- EXEC USP_UserRoles_Select ''  
  12. -- =============================================    
  13. CREATE PROCEDURE [dbo].[USP_UserRoles_Select]     
  14. (    
  15.      @Rolename             VARCHAR(30)     = ''   
  16.       )         
  17. AS                                                                  
  18. BEGIN         
  19.          Select ID,Name  
  20.             FROM   
  21.                 AspNetRoles   
  22.             WHERE  
  23.                 Name like  @Rolename +'%'  
  24. END  
  25.               
  26. -- 2) Stored procedure To Select all  Menu   
  27.   
  28. -- Author      : Shanu                                                                  
  29. -- Create date : 2016-01-30                                                                 
  30. -- Description :select all MenuMaster  detail                                            
  31. -- Tables used :  MenuMaster                                                              
  32. -- Modifier    : Shanu                                                                  
  33. -- Modify date : 2016-01-30                                                                  
  34. -- =============================================    
  35. -- To Select all menu master for Admin user.   
  36. -- EXEC USP_Menu_Select '',''  
  37. -- =============================================    
  38. CREATE PROCEDURE [dbo].[USP_Menu_Select]                                                
  39.    (                              
  40.      @MenuID           VARCHAR(30)     = '',  
  41.      @MenuName         VARCHAR(30)     = ''   
  42.       )                                                          
  43. AS                                                                  
  44. BEGIN      
  45.   
  46.          Select MenuIdentity ,    
  47.                MenuID ,    
  48.                MenuName ,  
  49.                Parent_MenuID  ,  
  50.                User_Roll,   
  51.                MenuFileName ,     
  52.                MenuURL ,    
  53.                USE_YN ,    
  54.                CreatedDate   
  55.             FROM   
  56.                 MenuMaster   
  57.             WHERE  
  58.                 MenuID like  @MenuID +'%'  
  59.                 AND MenuName like @MenuName +'%'  
  60.             --  AND USE_YN ='Y'  
  61.             ORDER BY  
  62.                 MenuName,MenuID   
  63.       
  64. END  
  65.   
  66. -- 3) Stored procedure To Select Menu by Logged in User Roll  
  67.   
  68. -- Author      : Shanu                                                                  
  69. -- Create date : 2016-01-30                                                                 
  70. -- Description :select all AspNetRoles   all roll name                                               
  71. -- Tables used :  AspNetRoles                                                              
  72. -- Modifier    : Shanu                                                                  
  73. -- Modify date : 2016-01-30                                                                  
  74. -- =============================================    
  75. -- To Select all user roles   
  76. -- EXEC USP_MenubyUserRole_Select 'Admin'  
  77. -- =============================================    
  78. CREATE PROCEDURE [dbo].[USP_MenubyUserRole_Select]     
  79. (    
  80.      @Rolename             VARCHAR(30)     = ''   
  81.       )         
  82. AS                                                                  
  83. BEGIN      
  84.       Select MenuIdentity ,    
  85.                MenuID ,    
  86.                MenuName ,  
  87.                Parent_MenuID  ,  
  88.                User_Roll,   
  89.                MenuFileName ,     
  90.                MenuURL ,    
  91.                USE_YN ,    
  92.                CreatedDate   
  93.             FROM   
  94.                 MenuMaster   
  95.             WHERE             
  96.                  User_Roll = @Rolename  
  97.                 AND USE_YN ='Y'  
  98.             ORDER BY  
  99.                 MenuName,MenuID       
  100.           
  101. END  
  102.   
  103.   
  104. -- 4) Stored procedure To Insert  Menu   
  105.   
  106. -- Author      : Shanu                                                                  
  107. -- Create date : 2016-01-30                                                                 
  108. -- Description :To Insert MenuMaster detail                                            
  109. -- Tables used :  MenuMaster                                                              
  110. -- Modifier    : Shanu                                                                  
  111. -- Modify date : 2016-01-30                                                                  
  112. -- =============================================    
  113. -- To Select all user roles   
  114. -- =============================================                                
  115. CREATE PROCEDURE [dbo].[USP_Menu_Insert]                                                
  116.    (                         
  117.      @MenuID            VARCHAR(30)     = '',  
  118.      @MenuName          VARCHAR(30)     = '',  
  119.      @Parent_MenuID     VARCHAR(30)     = '',  
  120.      @User_Roll         VARCHAR(200)     = '',  
  121.      @MenuFileName      VARCHAR(100)     = '',  
  122.      @MenuURL           VARCHAR(500)     = '',  
  123.      @USE_YN            VARCHAR(1)     = ''  
  124.       )                                                          
  125. AS                                                                  
  126. BEGIN         
  127.         IF NOT EXISTS (SELECT * FROM MenuMaster WHERE MenuID=@MenuID and MenuName=@MenuName)  
  128.             BEGIN  
  129.   
  130.                     INSERT INTO MenuMaster  
  131.                     (  MenuID ,     MenuName ,     Parent_MenuID  ,    User_Roll,      MenuFileName ,     
  132.                      MenuURL ,       USE_YN ,      CreatedDate )  
  133.                      VALUES (  @MenuID ,     @MenuName ,       @Parent_MenuID  ,       @User_Roll,     @MenuFileName ,     
  134.                      @MenuURL ,       @USE_YN ,        GETDATE())  
  135.                                  
  136.                     Select 'Inserted' as results  
  137.                           
  138.             END  
  139.          ELSE  
  140.              BEGIN  
  141.                      Select 'Exists' as results  
  142.               END  
  143.   
  144. END  
  145.   
  146. -- 5) Stored procedure To Update  Menu   
  147.   
  148. -- Author      : Shanu                                                                  
  149. -- Create date : 2016-01-30                                                                 
  150. -- Description :To Update MenuMaster detail                                            
  151. -- Tables used :  MenuMaster                                                              
  152. -- Modifier    : Shanu                                                                  
  153. -- Modify date : 2016-01-30                                                                  
  154. -- =============================================    
  155. -- To Select all user roles   
  156. -- =============================================                                  
  157. CREATE PROCEDURE [dbo].[USP_Menu_Update]                                                
  158.    ( @MenuIdentity             Int=0,                             
  159.      @MenuID            VARCHAR(30)     = '',  
  160.      @MenuName          VARCHAR(30)     = '',  
  161.      @Parent_MenuID     VARCHAR(30)     = '',  
  162.      @User_Roll         VARCHAR(200)     = '',  
  163.      @MenuFileName      VARCHAR(100)     = '',  
  164.      @MenuURL           VARCHAR(500)     = '',  
  165.      @USE_YN            VARCHAR(1)     = ''  
  166.       )                                                          
  167. AS                                                                  
  168. BEGIN         
  169.         IF  EXISTS (SELECT * FROM MenuMaster WHERE MenuIdentity=@MenuIdentity )  
  170.             BEGIN  
  171.                     UPDATE MenuMaster SET  
  172.                             MenuID=@MenuID,  
  173.                             MenuName=MenuName,  
  174.                             Parent_MenuID=@Parent_MenuID,  
  175.                             User_Roll=@User_Roll,  
  176.                             MenuFileName=@MenuFileName,  
  177.                             MenuURL=@MenuURL,  
  178.                             USE_YN=@USE_YN  
  179.                     WHERE  
  180.                     MenuIdentity=@MenuIdentity  
  181.                                  
  182.                     Select 'updated' as results                       
  183.             END  
  184.          ELSE  
  185.              BEGIN  
  186.                      Select 'Not Exists' as results  
  187.               END  
  188. END  
  189.   
  190.   
  191. -- 6) Stored procedure To Delete  Menu   
  192.   
  193. -- Author      : Shanu                                                                  
  194. -- Create date : 2016-01-30                                                                 
  195. -- Description :To Delete MenuMaster detail                                            
  196. -- Tables used :  MenuMaster                                                              
  197. -- Modifier    : Shanu                                                                  
  198. -- Modify date : 2016-01-30                                                                  
  199. -- =============================================    
  200. -- To Select all user roles   
  201. -- =============================================                                                            
  202. Create PROCEDURE [dbo].[USP_Menu_Delete]                                                
  203.    ( @MenuIdentity   Int=0 )                                                          
  204. AS                                                                  
  205. BEGIN         
  206.         DELETE FROM MenuMaster WHERE MenuIdentity=@MenuIdentity               
  207.               
  208. 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 no 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 has been selected for performing our Menu CRUD operations.
 
 
Here we can see now we have created our OrderDetailModel.


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 been missing and also GlobalConfiguration was not been added in Application_Start .

 
Here we add the reference and GlobalConfiguration like below to use WEB API. 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6. using System.Web.Optimization;  
  7. using System.Web.Routing;  
  8. using System.Web.Http;  
  9.   
  10. namespace shanuMVCUserRoles  
  11. {  
  12.     public class MvcApplication : System.Web.HttpApplication  
  13.     {  
  14.         protected void Application_Start()  
  15.         {  
  16.             AreaRegistration.RegisterAllAreas();  
  17.             GlobalConfiguration.Configure(WebApiConfig.Register);  
  18.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);  
  19.             RouteConfig.RegisterRoutes(RouteTable.Routes);  
  20.             BundleConfig.RegisterBundles(BundleTable.Bundles);  
  21.         }  
  22.     }  
  23. }  
In App_Star, WebApiConfig.cs change the routeTemplate like below,
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web.Http;  
  5.   
  6. namespace shanuMVCUserRoles  
  7. {  
  8.     public static class WebApiConfig  
  9.     {  
  10.         public static void Register(HttpConfiguration config)  
  11.         {  
  12.             // Web API configuration and services  
  13.   
  14.             // Web API routes  
  15.             config.MapHttpAttributeRoutes();  
  16.   
  17.             config.Routes.MapHttpRoute(  
  18.                 name: "DefaultApi",  
  19.                // routeTemplate: "api/{controller}/{id}",  
  20.                routeTemplate: "api/{controller}/{action}/{id}",  
  21.                 defaults: new { id = RouteParameter.Optional }  
  22.             );  
  23.         }  
  24.     }  
  25. }  
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. 

  1. // to Search Menu Details and display the result  
  2.         [HttpGet]  
  3.         public IEnumerable<USP_Menu_Select_Result> getMenuCRUDSelect(string menuID, string menuName)  
  4.         {  
  5.             if (menuID == null)  
  6.                 menuID = "";  
  7.             if (menuName == null)  
  8.                 menuName = "";        
  9.             return objapi.USP_Menu_Select(menuID, menuName).AsEnumerable();  
  10.         }  
We have created one more select method to get all User Role to bind in ComboBox in our MVC view using AngularJS. 
  1. // To get all user role from ASPNETRoels Table  
  2.         [HttpGet]  
  3.         public IEnumerable<USP_UserRoles_Select_Result> getUserRoleDetails(string UserRole)  
  4.         {  
  5.             if (UserRole == null)  
  6.                 UserRole = "";  
  7.             return objapi.USP_UserRoles_Select(UserRole).AsEnumerable();  
  8.         }  
Next we have one more Select method .This Method will be used to display menu for each user by their logged in role. 
  1. // To get all Menu by User role to bind the menu dynamically in user pages  
  2.         [HttpGet]  
  3.         public IEnumerable<USP_MenubyUserRole_Select_Result> getMenubyUserRole(string UserRole)  
  4.         {  
  5.             if (UserRole == null)  
  6.                 UserRole = "";  
  7.             return objapi.USP_MenubyUserRole_Select(UserRole).AsEnumerable();  
  8.         }  
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

The same as 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. 

  1. // To Insert new Menu Details  
  2.         [HttpGet]  
  3.         public IEnumerable<string> insertMenu(string menuID, string menuName, string parentMenuID, string UserRole, string menuFileName, string MenuURL, string UseYN)  
  4.         {  
  5.             return objapi.USP_Menu_Insert(menuID, menuName, parentMenuID, UserRole, menuFileName, MenuURL, UseYN).AsEnumerable();  
  6.         }  
Update Operation

The same as 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. 

  1. //to Update Menu Details  
  2.         [HttpGet]  
  3.         public IEnumerable<string> updateMenu(int MenuIdentity, string menuID, string menuName, string parentMenuID, string UserRole, string menuFileName, string MenuURL, string UseYN)  
  4.         {  
  5.             return objapi.USP_Menu_Update(MenuIdentity, menuID, menuName, parentMenuID, UserRole, menuFileName, MenuURL, UseYN).AsEnumerable();  
  6.         }  
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. 

  1. //to Delete Menu Details  
  2.         [HttpGet]  
  3.         public string deleteMenu(int MenuIdentity)  
  4.         {  
  5.             objapi.USP_Menu_Delete(MenuIdentity);  
  6.             objapi.SaveChanges();  
  7.             return "deleted";  
  8.         }  
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 AngularJS JavaScript and create an Angular Module named “RESTClientModule”. 

  1. // <reference path="../angular.js" />    
  2. /// <reference path="../angular.min.js" />     
  3. /// <reference path="../angular-animate.js" />     
  4. /// <reference path="../angular-animate.min.js" />     
  5. var app;  
  6. (function () {  
  7.     app = angular.module("RESTClientModule", ['ngAnimate']);  
  8. })();  
Controllers: In AngularJS Controller I have done all the business logic and returned the data from Web API to our MVC HTML page.

1. Variable declarations

Firstly, we declared all the local variables need to be used.
 

  1. app.controller("AngularJs_Controller"function ($scope, $timeout, $rootScope, $window, $http) {  
  2.     $scope.date = new Date();  
  3.     $scope.MyName = "shanu";  
  4.     $scope.sMenuID = "";  
  5.     $scope.sMenuName = "";  
  6.   
  7.     $scope.showMenuAdd = true;  
  8.     $scope.addEditMenu = false;  
  9.     $scope.MenuList = true;  
  10.     $scope.showItem = true;  
  11.     $scope.userRoleName = $("#txtuserRoleName").val();// this is hidden textbox which will be storing our logged in user Role Name.  
  12.     //This variable will be used for Insert/Edit/Delete menu details.  menuID, menuName, parentMenuID, UserRole, menuFileName, MenuURL, UseYN  
  13.     $scope.MenuIdentitys = 0;  
  14.     $scope.menuIDs = "";  
  15.     $scope.menuNames = "";  
  16.     $scope.parentMenuIDs = "";  
  17.     $scope.selectedUserRole = "";  
  18.     $scope.menuFileNames = "";  
  19.     $scope.MenuURLs = "";  
  20.     $scope.UseYNs = true;  
  21.     $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:

  1. { params: { menuID: menuID, menuName: menuName }  

The final result will be displayed to the MVC HTML page using data-ng-repeat. 

  1. //This method is used to search and display the Menu Details for display,Edit and Delete  
  2.     select MenuDetails($scope.sMenuID, $scope.sMenuName);  
  3.   
  4.     function selectMenuDetails(menuID, menuName) {  
  5.        
  6.         $http.get('/api/MenuAPI/getMenuCRUDSelect/', { params: { menuID: menuID, menuName: menuName } }).success(function (data) {  
  7.             $scope.MenuData = data;  
  8.             $scope.showMenuAdd = true;  
  9.             $scope.addEditMenu = false;  
  10.             $scope.MenuList = true;  
  11.             $scope.showItem = true;  
  12.   
  13.             if ($scope.MenuData.length > 0) {  
  14.             }  
  15.         })  
  16.    .error(function () {  
  17.        $scope.error = "An Error has occured while loading posts!";  
  18.    });  
  19.   
  20.         //Here we call all the created menu details to bind in select list for creating sub menu  
  21.         $http.get('/api/MenuAPI/getMenuCRUDSelect/', { params: { menuID: "", menuName: "" } }).success(function (data) {  
  22.             $scope.MenuDataSelect = data;          
  23.             
  24.         })  
  25.   .error(function () {  
  26.       $scope.error = "An Error has occured while loading posts!";  
  27.   });  
  28.                  
  29.     }  
  30.   
  31.     //Search  
  32.     $scope.searchMenuDetails = function () {  
  33.   
  34.         selectMenuDetails($scope.sMenuID, $scope.sMenuName);  
  35.     }  
Search Button Click 
  1. <table style="color:#9F000F;font-size:large" cellpadding="4" cellspacing="6">  
  2.   
  3.                                             <tr>  
  4.                                                 <td>  
  5.                                                     <b>Menu ID</b>  
  6.                                                 </td>  
  7.   
  8.                                                 <td>  
  9.                                                     : <input type="text" name="txtMenuID" ng-model="sMenuID" value="" />  
  10.                                                     <br />  
  11.                                                 </td>  
  12.   
  13.                                                 <td>  
  14.                                                     <b>   Menu Name </b>  
  15.                                                 </td>  
  16.   
  17.                                                 <td>  
  18.                                                     :  
  19.                                                     <input type="text" name="txtMenuName" ng-model="sMenuName" />  
  20.   
  21.                                                 </td>  
  22.                                                 <td>  
  23.                                                     <input type="submit" value="Search" style="background-color:#336699;color:#FFFFFF" ng-click="searchMenuDetails()" />  
  24.   
  25.                                                 </td>  
  26.                                             </tr>  
  27.   
  28.   
  29.                                         </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. 

  1. // New Menu Add Details  
  2.     $scope.showMenuAddDetails = function () {  
  3.         cleardetails();  
  4.         $scope.showMenuAdd = true;  
  5.         $scope.addEditMenu = true;  
  6.         $scope.MenuList = true;  
  7.         $scope.showItem = true;  
  8.   
  9.     }  
User Roles bind to Combobox

For creating new menu Admin need to select User Role. For this we will bind all the ASP.NET Roles table all role details to the combobox .

AngularJS Conroller part:

Using our WEbAPI we get all the User Roles and store the result in $scope.userRoleData

  1. // This method is to get all the UserRole and bind to dropdownbox selection for creating menu by User Role.   
  2. select userRoleDetails($scope.searchRoleName);  
  3. // This method is to get all the UserRole and bind to dropdownbox selection for creating menu by User Role.   
  4. function selectuerRoleDetails(UserRole) {        
  5.     $http.get('/api/MenuAPI/getUserRoleDetails/', { params: { UserRole: UserRole } }).success(function (data) {  
  6.        
  7.         $scope.userRoleData = data;  
  8.     })  
  9. rror(function () {  
  10.   $scope.error = "An Error has occured while loading posts!";  
  11. ;  
  12. }  

Html part to bind Combobox with user roles

  1. <select name="opSelect" id="opSelect" ng-model="selectedUserRole">  
  2.  <option value="" selected>-- Select --</option>  
  3.  <option ng-repeat="option in userRoleData" value="{{option.Name}}">{{option.Name}}</option>  
  4. </select>  

Parent Menu ID bind to Combobox

For creating sub menu admin can select parent menu from ComboBox. Every time when admin create a Menu the main menu ID will be added to this combobox for creating sub menu.

AngularJS Conroller 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

  1. <select name="opSelect" id="opSelect" ng-model="parentMenuIDs">  
  2. <option value="*" selected>*</option>  
  3.   <option ng-repeat="option in MenuDataSelect" value="{{option.MenuID}}">{{option.MenuID}}</option>  
  4. </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.
  1. //Save Menu  
  2.     $scope.saveDetails = function () {  
  3.         if ($scope.selectedUserRole == "")  
  4.         {  
  5.             alert("Select User Role");  
  6.             return;  
  7.         }  
  8.         
  9.         if ($scope.parentMenuIDs == "") {  
  10.             alert("Select parent ID");  
  11.             return;  
  12.         }  
  13.   
  14.         $scope.IsFormSubmitted = true;  
  15.         if ($scope.IsFormValid) {  
  16.             
  17.             if ($scope.UseYNs == true)  
  18.             {  
  19.                 $scope.UseYNsN = "Y";  
  20.             }  
  21.             else  
  22.             {  
  23.                 $scope.UseYNsN = "N";  
  24.             }  
  25.              
  26.   
  27.             //if the MenuIdentity ID=0 means its new Menu insert here i will call the Web api insert method  
  28.             if ($scope.MenuIdentitys == 0) {  
  29.   
  30.                 $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) {  
  31.   
  32.                     $scope.menuInserted = data;  
  33.                     alert($scope.menuInserted);  
  34.   
  35.   
  36.                     cleardetails();  
  37.                     selectMenuDetails('''');  
  38.                     selectMenubyUserRoleDetails($scope.userRoleName);  
  39.                 })  
  40.          .error(function () {  
  41.              $scope.error = "An Error has occured while loading posts!";  
  42.          });  
  43.             }  
  44.             
  45.   
  46.             else {  // to update to the Menu details  
  47.                 $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) {  
  48.                     $scope.menuUpdated = data;  
  49.                     alert($scope.menuUpdated);  
  50.   
  51.                     cleardetails();  
  52.                     selectMenuDetails('''');  
  53.                     selectMenubyUserRoleDetails($scope.userRoleName);  
  54.                 })  
  55.         .error(function () {  
  56.             $scope.error = "An Error has occured while loading posts!";  
  57.         });  
  58.             }  
  59.   
  60.         }  
  61.         else {  
  62.             $scope.Message = "All the fields are required.";  
  63.         }  
  64.   
  65.         $scope.IsFormSubmitted = false;  
  66.     }  
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 be only visible to Employee Role users not even to Admin and Parent menu ID as ‘*’ which is for display 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 was been not 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. 
  1. //Delete Menu Detail  
  2.     $scope.MenuDelete = function MenuDelete(MenuIdentity, menuName) {  
  3.         cleardetails();  
  4.         $scope.MenuIdentitys = MenuIdentity;  
  5.         var delConfirm = confirm("Are you sure you want to delete the Student " + menuName + " ?");  
  6.         if (delConfirm == true) {  
  7.   
  8.             $http.get('/api/MenuAPI/deleteMenu/', { params: { MenuIdentity: $scope.MenuIdentitys } }).success(function (data) {  
  9.                 alert("Menu Deleted Successfully!!");  
  10.                 cleardetails();  
  11.                 selectMenuDetails('''');  
  12.             })  
  13.       .error(function () {  
  14.           $scope.error = "An Error has occured while loading posts!";  
  15.       });  
  16.   
  17.         }  
  18.     }  
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. 

  1. <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. 
  1. $scope.userRoleName = $("#txtuserRoleName").val();  
  2.   
  3. //********** ---------------- for Disoplay Menu by User Role -------------   ***************  
  4.     // This method is to get all the menu details of logged in users .Bind this result for creating Menu  
  5.     selectMenubyUserRoleDetails($scope.userRoleName);  
  6.     // This method is to get all the menu details of logged in users .Bind this result for creating Menu  
  7.     function selectMenubyUserRoleDetails(UserRole) {  
  8.        // alert($scope.userRoleName);  
  9.         $http.get('/api/MenuAPI/getMenubyUserRole/', { params: { UserRole: $scope.userRoleName } }).success(function (data) {  
  10.             $scope.generateMenuData = data;  
  11.         })  
  12.  .error(function () {  
  13.      $scope.error = "An Error has occured while loading posts!";  
  14.  });  
  15.   
  16.     }  
  17.   
  18.     $scope.showDetails = false;  
  19.     $scope.showSubDetails = false;  
  20.     $scope.subChildIDS = "";  
  21.     $scope.Imagename = "R1.png";  
  22.     $scope.showsubMenu = function (showMenus, ids) {  
  23.   
  24.         if (showMenus == 1) {  
  25.             $scope.subChildIDS = ids;  
  26.   
  27.             $scope.showSubDetails = true;  
  28.         }  
  29.         else if (showMenus == 0) {  
  30.             $scope.showSubDetails = false;  
  31.         }  
  32.         else {  
  33.   
  34.             $scope.showSubDetails = true;  
  35.         }  
  36.     }  
  37.   
  38.     //********** ---------------- End Disoplay Menu -------------   ***************  
In our view page we bind the menu result to table to display all menu and sub menu like below. 
  1. <div style="overflow:visible;height:100px;">  
  2.                                 <ul class="menu">  
  3.                                     <li data-ng-repeat="menus in generateMenuData | filter:{Parent_MenuID:'*'}">  
  4.                                         @{var url = Url.Action("{{menus.MenuFileName}}", "{{menus.MenuURL}}", new { id = "{{id=menus.MenuURL}}" });  
  5.                                             url = HttpUtility.UrlDecode(url);  
  6.                                         }  
  7.                                         <a data-ng-href="@url">{{menus.MenuName}}</a>  
  8.   
  9.                                         <ul class="sub-menu">  
  10.                                             <li data-ng-repeat="submenus in generateMenuData | filter:{Parent_MenuID:menus.MenuID}" ng-mouseover="showsubMenu(1,submenus.MenuID);" ng-mouseout="showsubMenu(0,submenus.MenuID);">  
  11.                                                 @{var url1 = Url.Action("{{submenus.MenuFileName}}", "{{submenus.MenuURL}}", new { id = "{{id=submenus.MenuURL}}" });  
  12.                                                     url1 = HttpUtility.UrlDecode(url1);  
  13.                                                 }  
  14.                                                 <a data-ng-href="@url1">{{submenus.MenuName}}</a>  
  15.   
  16.                                                 <ul ng-show="showSubDetails" class="sub-menu2">  
  17.                                                     <li data-ng-repeat="sub1menus in generateMenuData  | filter:{Parent_MenuID:submenus.MenuID}" ng-mouseover="showsubMenu(3,9);">  
  18.                                                         @{var url2 = Url.Action("{{sub1menus.MenuFileName}}", "{{sub1menus.MenuURL}}", new { id = "{{id=sub1menus.MenuURL}}" });  
  19.                                                             url2 = HttpUtility.UrlDecode(url2);  
  20.                                                         }  
  21.                                                         <a data-ng-href="@url2">{{sub1menus.MenuName}}</a>  
  22.                                                     </li>  
  23.                                                 </ul>  
  24.                                             </li>  
  25.                                         </ul>  
  26.                                     </li>  
  27.                                 </ul>  
  28.                             </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. 

  1. public string RoleName { get; set; }  
  2.         // GET: Users  
  3.           
  4.         public ActionResult Index()  
  5.         {  
  6.             if (User.Identity.IsAuthenticated)  
  7.             {  
  8.                 var user = User.Identity;  
  9.                 ViewBag.Name = user.Name;  
  10.                 ApplicationDbContext context = new ApplicationDbContext();  
  11.                 var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));  
  12.                 var s = UserManager.GetRoles(user.GetUserId());  
  13.                 RoleName = s[0].ToString();  
  14.                 ViewBag.displayMenu = "No";  
  15.                 ViewBag.UserRole = RoleName;  
  16.                 if (RoleName == "Admin")  
  17.                 {                 
  18.                     ViewBag.displayMenu = "Yes";  
  19.                 }  
  20.                   
  21.                 return View();  
  22.             }  
  23.             else  
  24.             {  
  25.             return  RedirectToAction("Index""Home");  
  26.             }  
  27.   
  28.         }  
Conclusion

Firstly, run all the script to your SQL Server you can also find the SQL Script file from attached zip file. After your 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.