MVC - Dynamic Menu With WCF REST and AngularJS

Dynamic Menu means reading menu and their sub-menus from the database table. I have the following SQL Server data table where you can see the Menu Information:

MENU table in Design Mode:


                                                Figure 1

Script of this Table:

  1. CREATE TABLE [dbo].[Menu](  
  2.     [Menu_ID] [int] IDENTITY(1,1) NOT NULL,  
  3.     [Menu_Parent_ID] [intNULL,  
  4.     [Menu_Name] [varchar](100) NULL,  
  5.     [ActionMethodName] [varchar](100) NULL,  
  6.     [ControllerName] [varchar](100) NULL,  
  7.  CONSTRAINT [PK_Menu] PRIMARY KEY CLUSTERED   
  8. (  
  9.     [Menu_ID] ASC  
  10. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]  
  11. ON [PRIMARY]  
  12.   
  13. GO  
Now understand this table by data:


                                                                              Figure 2

Here in this table I have record with Menu_ID & Menu_Parent_ID relation. From here we can identify which menu has submenu.

Queries


                                                                      Figure 3


                                                              Figure 4




                                                                  Figure 5

Above queries will help you to understand Menu Structure in the database table.

Now time to create a Visual Studio Application. Here I will use WCF REST and AngularJS.

Open Visual Studio, then New and go to Project. Add a WCF Service Application project like the following:


                                                                            Figure 6


Remove Service.svc and IService.cs. Right click on Project Solution Explorer, then add WCF Service:


                                                                              Figure 7


Now again right click on Project Solution Explore.

(DynamicMenu_MVC_AngularJS_WCFService) - Add New Item


                                                                           Figure 8


                                                                                 Figure 9


                                                               Figure 10


                                                                              Figure 11


                                                                                    Figure 12


                                                   Figure 13

Now add a new class MenuItem.cs to define DataContract.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Runtime.Serialization;  
  6. using System.ServiceModel;  
  7.   
  8. namespace DynamicMenu_MVC_AngularJS_WCFService  
  9. {  
  10.     public class MenuItem  
  11.     {  
  12.         [DataContract]  
  13.         public class MenuDetailDataContract  
  14.         {  
  15.             [DataMember]  
  16.             public string Menu_ID { getset; }  
  17.   
  18.             [DataMember]  
  19.             public string Menu_Parent_ID { getset; }  
  20.   
  21.             [DataMember]  
  22.             public string Menu_Name { getset; }  
  23.   
  24.             [DataMember]  
  25.             public string ActionMethodName { getset; }  
  26.   
  27.             [DataMember]  
  28.             public string ControllerName { getset; }  
  29.         }  
  30.     }  
  31. }  

                                                                              Figure 14

Now open IMenuService.cs:
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Runtime.Serialization;  
  5. using System.ServiceModel;  
  6. using System.ServiceModel.Web;  
  7. using System.Text;  
  8.   
  9. namespace DynamicMenu_MVC_AngularJS_WCFService  
  10. {  
  11.     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IMenuService" in both code and config file together.  
  12.     [ServiceContract]  
  13.     public interface IMenuService  
  14.     {  
  15.         [OperationContract]  
  16.         [WebInvoke(Method = "GET",  
  17.           RequestFormat = WebMessageFormat.Json,  
  18.           ResponseFormat = WebMessageFormat.Json,  
  19.           UriTemplate = "/GetMenuDetails/")]  
  20.         List<MenuItem.MenuDetailDataContract> GetMenuDetails();  
  21.     }  
  22. }  

                                                                              Figure 15

Now open MenuService.svc:
  1. using System.Collections.Generic;  
  2. using System.Linq;  
  3. using System.Runtime.Serialization;  
  4. using System.ServiceModel;  
  5. using System.ServiceModel.Web;  
  6. using System.Text;  
  7. namespace DynamicMenu_MVC_AngularJS_WCFService  
  8. {  
  9.     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "MenuService" in code, svc and config file together.  
  10.     // NOTE: In order to launch WCF Test Client for testing this service, please select MenuService.svc or MenuService.svc.cs at the Solution Explorer and start debugging.  
  11.     public class MenuService : IMenuService  
  12.     {  
  13.         DynamicMenu_MVC_AngularJS_WCFService.TestDBEntities1 OME;  
  14.   
  15.         public MenuService()  
  16.         {  
  17.             OME = new DynamicMenu_MVC_AngularJS_WCFService.TestDBEntities1();  
  18.         }  
  19.   
  20.         public List<MenuItem.MenuDetailDataContract> GetMenuDetails()  
  21.         {  
  22.             var query = (from A in OME.Menu  
  23.                          select new  
  24.                          {  
  25.                              A.Menu_ID,  
  26.                              A.Menu_Parent_ID,  
  27.                              A.Menu_Name,  
  28.                              A.ActionMethodName,  
  29.                              A.ControllerName  
  30.                          }).ToList();  
  31.   
  32.             List<MenuItem.MenuDetailDataContract> MenuList = new List<MenuItem.MenuDetailDataContract>();  
  33.   
  34.             query.ToList().ForEach(rec =>  
  35.             {  
  36.                 MenuList.Add(new MenuItem.MenuDetailDataContract  
  37.                 {  
  38.                     Menu_ID = Convert.ToString(rec.Menu_ID),  
  39.                     Menu_Parent_ID = rec.Menu_Parent_ID.ToString(),  
  40.                     Menu_Name = rec.Menu_Name.ToString(),  
  41.                     ActionMethodName = rec.ActionMethodName,  
  42.                     ControllerName = rec.ControllerName  
  43.                 });  
  44.             });  
  45.             return MenuList;  
  46.         }  
  47.     }  
  48. }  

                                                                                 Figure 16

Make sure your WCF Service web.config file should have <ServiceModel> like the following:
  1. <system.serviceModel>  
  2.     <behaviors>  
  3.       <serviceBehaviors>  
  4.         <behavior>  
  5.           <!-- To avoid disclosing metadata information, set the values below to false before deployment -->  
  6.           <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />  
  7.           <!-- To receive exception details in faults for debugging purposes,   
  8.           set the value below to true.  Set to false before deployment  
  9.           to avoid disclosing exception information -->  
  10.           <serviceDebug includeExceptionDetailInFaults="false" />  
  11.         </behavior>  
  12.       </serviceBehaviors>  
  13.       <endpointBehaviors>  
  14.         <behavior>  
  15.           <webHttp helpEnabled="True" />  
  16.         </behavior>  
  17.       </endpointBehaviors>  
  18.     </behaviors>  

                                                                                 Figure 17

Now build your WCF Service.

Now time to add a new MVC project. Right click on your project solution explorer, click Add, then New Project.


                                                                              Figure 18


                                                                           Figure 19


                                                                        Figure 20

Now Add your WCF Service reference in your MVC project: Steps To Add WCF Service Reference.

Run your WCF Service.Copy WCF Service URL, Right click on MVC project, then Add Service Reference


                                                               Figure 21


                                                                           Figure 22

As I told you that I am going to show dynamic menu using AngularJS, so we need to add AngularJS reference.

Right click on your MVC Project’s Solution Explorer, then ManageNuGet and click Search Angular:


                                                                           Figure 23

Now time to add AngularJS Module.js, Controller.js and Service.js.

Create a new folder under: MVC Project, Scripts, then MyScripts.

Add the following three js files:
  1. Module.js
    1. /// <reference path="../angular.js" />   
    2. /// <reference path="../angular.min.js" />     
    3.   
    4. var app;  
    5.   
    6. (function () {  
    7.     app = angular.module("RESTClientModule", []);  
    8. })();  

                                                                                  Figure 24

  2. Service.js
    1. /// <reference path="../angular.js" />    
    2. /// <reference path="../angular.min.js" />    
    3. /// <reference path="Modules.js" />     
    4.   
    5. app.service("AngularJs_WCFService", function ($http) {  
    6.     //Get Order Master Records    
    7.     this.geMenuDetails = function () {  
    8.         return $http.get("http://localhost:22131/MenuService.svc/GetMenuDetails");  
    9.     };  
    10. });  

                                                                                Figure 25


  3. Controller.js
    1. /// <reference path="../angular.js" />    
    2. /// <reference path="../angular.min.js" />     
    3. /// <reference path="Modules.js" />     
    4. /// <reference path="Services.js" />     
    5.   
    6. app.controller("MVCDynamicMenuWCF_Controller", function ($scope, $window, AngularJs_WCFService) {  
    7.     $scope.date = new Date();  
    8.     $scope.showDetails = false;   
    9.   
    10.     getAllMenuDetails();  
    11.   
    12.     function getAllMenuDetails() {  
    13.         var promiseGet = AngularJs_WCFService.geMenuDetails();  
    14.         promiseGet.then(function (pl) {  
    15.             $scope.MenuDetailsDisp = pl.data  
    16.         },  
    17.              function (errorPl) {  
    18.              });  
    19.     }  
    20.   
    21.     $scope.showMenu = function (showMenus) {  
    22.         if (showMenus == 1) {   
    23.             $scope.showDetails = true;  
    24.         }  
    25.         else {   
    26.             $scope.showDetails = false;  
    27.         }  
    28.     }  
    29.   
    30.     $scope.showsubMenu = function (showMenus, ids) {  
    31.         if (showMenus == 1) {  
    32.             $scope.subChildIDS = ids;  
    33.             $scope.showSubDetails = true;  
    34.         }  
    35.         else if (showMenus == 0) {  
    36.             $scope.showSubDetails = false;  
    37.         }  
    38.         else {  
    39.             $scope.showSubDetails = true;  
    40.         }  
    41.     }  
    42. });  

                                                                                  Figure 26

    Now Add a new controller & View in which you want to show your Dynamic menus. In my case I am showing these in Home, then Index.cshtml

My Index.cshtml is the following:

  1. <style>  
  2.     ul, li {  
  3.         list-style-type: none;  
  4.         margin: 0;  
  5.         padding: 0;  
  6.     }  
  7.     .menu {  
  8.         background: blue;  
  9.         height: 5px;  
  10.         color: #FFFFFF;  
  11.     }  
  12.         .menu > li {  
  13.             display: inline-block;  
  14.             padding: 2px 6px 22px 2px;  
  15.             display: inline-block;  
  16.             text-align: center;  
  17.             height: 10px;  
  18.             width: 176px;  
  19.             color: #0094ff;  
  20.             background: #0094ff;  
  21.         }  
  22.             .menu > li a {  
  23.                 display: inline-block;  
  24.                 padding: 2px 6px 22px 2px;  
  25.                 display: inline-block;  
  26.                 text-align: center;  
  27.                 height: 10px;  
  28.                 width: 176px;  
  29.                 color: #FFFFFF;  
  30.                 background: green;  
  31.             }  
  32.                 .menu > li a:hover {  
  33.                     display: inline-block;  
  34.                     padding: 2px 6px 22px 2px;  
  35.                     display: inline-block;  
  36.                     text-align: center;  
  37.                     height: 10px;  
  38.                     width: 176px;  
  39.                     color: #000000;  
  40.                     background: yellow;  
  41.                 }  
  42.   
  43.     .sub-menu {  
  44.         position: absolute;  
  45.         display: none;  
  46.         background-color: transparent;  
  47.         padding: 5px;  
  48.     }  
  49.   
  50.         .sub-menu > li {  
  51.             display: block;  
  52.             cursor: pointer;  
  53.         }  
  54.   
  55.             .sub-menu > li a:hover {  
  56.                 display: block;  
  57.                 cursor: pointer;  
  58.                 background: yellow;  
  59.             }  
  60.   
  61.   
  62.     li:hover .sub-menu {  
  63.         display: block;  
  64.     }  
  65. </style>  
  66. <html data-ng-app="RESTClientModule">  
  67. @{  
  68.     ViewBag.Title = "MVC- Dynamic Menu using WCF REST & AngularJS";      
  69. }  
  70. <body data-ng-controller="MVCDynamicMenuWCF_Controller">  
  71.     <div class="navbar navbar-inverse navbar-fixed-top">  
  72.         <div class="container">  
  73.             <div class="navbar-collapse collapse">  
  74.                 <div style="overflow: visible;">  
  75.                     <ul class="menu">  
  76.                         <li data-ng-repeat="menus in MenuDetailsDisp | filter:{Menu_Parent_ID:'0'}">  
  77.                             @{  
  78.                                 var url = Url.Action("{{menus.ActionMethodName}}""{{menus.ControllerName}}"new { id = "{{id=menus.ActionMethodName}}" });  
  79.                                 url = HttpUtility.UrlDecode(url);  
  80.                             }  
  81.                             <a data-ng-href="@url">{{menus.Menu_Name}}</a>  
  82.   
  83.                             <ul class="sub-menu">  
  84.                                 <li data-ng-repeat="submenus in MenuDetailsDisp | filter:{Menu_Parent_ID:menus.Menu_ID}:true" ng-mouseover="showsubMenu(1,submenus.Menu_ID);" ng-mouseout="showsubMenu(0,submenus.Menu_ID);">  
  85.                                     @{  
  86.                                         var url1 = Url.Action("{{submenus.ActionMethodName}}""{{submenus.ControllerName}}"new { id = "{{id=submenus.ActionMethodName}}" });  
  87.                                         url1 = HttpUtility.UrlDecode(url1);  
  88.                                     }  
  89.                                     <a data-ng-href="@url1">{{submenus.Menu_Name}}</a>  
  90.                                 </li>  
  91.                             </ul>  
  92.                         </li>  
  93.                     </ul>  
  94.                 </div>  
  95.             </div>  
  96.         </div>  
  97.     </div>  
  98.     <div style="height: 200px;"></div>  
  99. </body>  
  100. </html>  
  101. <script src="~/Scripts/angular.js"></script>  
  102. <script src="~/Scripts/MyScripts/Modules.js"></script>  
  103. <script src="~/Scripts/MyScripts/Services.js"></script>  
  104. <script src="~/Scripts/MyScripts/controller.js"></script>  
Now Run your application


                                                                           Figure 27

 
                                                                           Figure 28



                                                                          Figure 29


                                                                           Figure 30


                                                                              Figure 31


                                                                           Figure 32


                                                                           Figure 33 


Similar Articles