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] [int] NULL,
  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 = ON) ON [PRIMARY]
  11. ) ON [PRIMARY]
  12. 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. namespace DynamicMenu_MVC_AngularJS_WCFService
  8. {
  9. public class MenuItem
  10. {
  11. [DataContract]
  12. public class MenuDetailDataContract
  13. {
  14. [DataMember]
  15. public string Menu_ID { get; set; }
  16. [DataMember]
  17. public string Menu_Parent_ID { get; set; }
  18. [DataMember]
  19. public string Menu_Name { get; set; }
  20. [DataMember]
  21. public string ActionMethodName { get; set; }
  22. [DataMember]
  23. public string ControllerName { get; set; }
  24. }
  25. }
  26. }

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. namespace DynamicMenu_MVC_AngularJS_WCFService
  9. {
  10. // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IMenuService" in both code and config file together.
  11. [ServiceContract]
  12. public interface IMenuService
  13. {
  14. [OperationContract]
  15. [WebInvoke(Method = "GET",
  16. RequestFormat = WebMessageFormat.Json,
  17. ResponseFormat = WebMessageFormat.Json,
  18. UriTemplate = "/GetMenuDetails/")]
  19. List<MenuItem.MenuDetailDataContract> GetMenuDetails();
  20. }
  21. }

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. public MenuService()
  15. {
  16. OME = new DynamicMenu_MVC_AngularJS_WCFService.TestDBEntities1();
  17. }
  18. public List<MenuItem.MenuDetailDataContract> GetMenuDetails()
  19. {
  20. var query = (from A in OME.Menu
  21. select new
  22. {
  23. A.Menu_ID,
  24. A.Menu_Parent_ID,
  25. A.Menu_Name,
  26. A.ActionMethodName,
  27. A.ControllerName
  28. }).ToList();
  29. List<MenuItem.MenuDetailDataContract> MenuList = new List<MenuItem.MenuDetailDataContract>();
  30. query.ToList().ForEach(rec =>
  31. {
  32. MenuList.Add(new MenuItem.MenuDetailDataContract
  33. {
  34. Menu_ID = Convert.ToString(rec.Menu_ID),
  35. Menu_Parent_ID = rec.Menu_Parent_ID.ToString(),
  36. Menu_Name = rec.Menu_Name.ToString(),
  37. ActionMethodName = rec.ActionMethodName,
  38. ControllerName = rec.ControllerName
  39. });
  40. });
  41. return MenuList;
  42. }
  43. }
  44. }

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. var app;
    4. (function () {
    5. app = angular.module("RESTClientModule", []);
    6. })();

    Figure 24

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

    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. app.controller("MVCDynamicMenuWCF_Controller", function ($scope, $window, AngularJs_WCFService) {
    6. $scope.date = new Date();
    7. $scope.showDetails = false;
    8. getAllMenuDetails();
    9. function getAllMenuDetails() {
    10. var promiseGet = AngularJs_WCFService.geMenuDetails();
    11. promiseGet.then(function (pl) {
    12. $scope.MenuDetailsDisp = pl.data
    13. },
    14. function (errorPl) {
    15. });
    16. }
    17. $scope.showMenu = function (showMenus) {
    18. if (showMenus == 1) {
    19. $scope.showDetails = true;
    20. }
    21. else {
    22. $scope.showDetails = false;
    23. }
    24. }
    25. $scope.showsubMenu = function (showMenus, ids) {
    26. if (showMenus == 1) {
    27. $scope.subChildIDS = ids;
    28. $scope.showSubDetails = true;
    29. }
    30. else if (showMenus == 0) {
    31. $scope.showSubDetails = false;
    32. }
    33. else {
    34. $scope.showSubDetails = true;
    35. }
    36. }
    37. });

    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. .sub-menu {
  43. position: absolute;
  44. display: none;
  45. background-color: transparent;
  46. padding: 5px;
  47. }
  48. .sub-menu > li {
  49. display: block;
  50. cursor: pointer;
  51. }
  52. .sub-menu > li a:hover {
  53. display: block;
  54. cursor: pointer;
  55. background: yellow;
  56. }
  57. li:hover .sub-menu {
  58. display: block;
  59. }
  60. </style>
  61. <html data-ng-app="RESTClientModule">
  62. @{
  63. ViewBag.Title = "MVC- Dynamic Menu using WCF REST & AngularJS";
  64. }
  65. <body data-ng-controller="MVCDynamicMenuWCF_Controller">
  66. <div class="navbar navbar-inverse navbar-fixed-top">
  67. <div class="container">
  68. <div class="navbar-collapse collapse">
  69. <div style="overflow: visible;">
  70. <ul class="menu">
  71. <li data-ng-repeat="menus in MenuDetailsDisp | filter:{Menu_Parent_ID:'0'}">
  72. @{
  73. var url = Url.Action("{{menus.ActionMethodName}}", "{{menus.ControllerName}}", new { id = "{{id=menus.ActionMethodName}}" });
  74. url = HttpUtility.UrlDecode(url);
  75. }
  76. <a data-ng-href="@url">{{menus.Menu_Name}}</a>
  77. <ul class="sub-menu">
  78. <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);">
  79. @{
  80. var url1 = Url.Action("{{submenus.ActionMethodName}}", "{{submenus.ControllerName}}", new { id = "{{id=submenus.ActionMethodName}}" });
  81. url1 = HttpUtility.UrlDecode(url1);
  82. }
  83. <a data-ng-href="@url1">{{submenus.Menu_Name}}</a>
  84. </li>
  85. </ul>
  86. </li>
  87. </ul>
  88. </div>
  89. </div>
  90. </div>
  91. </div>
  92. <div style="height: 200px;"></div>
  93. </body>
  94. </html>
  95. <script src="~/Scripts/angular.js"></script>
  96. <script src="~/Scripts/MyScripts/Modules.js"></script>
  97. <script src="~/Scripts/MyScripts/Services.js"></script>
  98. <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