In this article I am going to show how we can create
Dynamic menu in MVC application with AngularJS.
Dynamic Menu mean reading Menu and their sub Menu from
Data Base table. I have below SQL Server data table where I am having my Menu
Information:
MENU
table in Design Mode:

Image 1.
Script
of this Table:
CREATE TABLE [dbo].[Menu](
[Menu_ID]
[int] IDENTITY(1,1) NOT NULL,
[Menu_Parent_ID]
[int] NULL,
[Menu_Name]
[varchar](100) NULL,
[ActionMethodName]
[varchar](100) NULL,
[ControllerName]
[varchar](100) NULL,
CONSTRAINT [PK_Menu] PRIMARY
KEY CLUSTERED
(
[Menu_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS
= ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Now understand this table by Data:

Image 2.
Here in this table I have record with Menu_ID &
Menu_Parent_ID relation. Mean from here we can identify which menu have
submenu.
See
below Queries:

Image 3.

Image 4.
Now see:

Image 5.
Hoe above queries will help you to understand Menu
Structure in Data base Table.
Now time to come create a Visual Studio Application.
Here I will use WCF REST and AngularJS.
So Open Visual Studio -> New-> Project -> Add
a WCF Project like Below:

Image 6.
Remove Service.svc and IService.cs. Right Click on
Project Solution Explorer -> Add WCF Service:

Image 7.
Now again Right Click on Project Solution Explorer (DynamicMenu_MVC_AngularJS_WCFService)
-> Add New Item

Image 8.

Image 9.

Image 10.

Image 11.

Image 12.

Image 13.
Now add a new class MenuItem.cs to define DataContract
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Web;
using
System.Runtime.Serialization;
using
System.ServiceModel;
namespace
DynamicMenu_MVC_AngularJS_WCFService
{
public class MenuItem
{
[DataContract]
public class MenuDetailDataContract
{
[DataMember]
public string Menu_ID { get; set; }
[DataMember]
public string Menu_Parent_ID { get; set; }
[DataMember]
public string Menu_Name { get; set; }
[DataMember]
public string ActionMethodName { get; set; }
[DataMember]
public string ControllerName { get; set; }
}
}
}

Image 14.
Now
open IMenuService.cs:
using System;
using
System.Collections.Generic;
using System.Linq;
using
System.Runtime.Serialization;
using
System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace
DynamicMenu_MVC_AngularJS_WCFService
{
// NOTE: You can use the
"Rename" command on the "Refactor" menu to change the
interface name "IMenuService" in both code and config file together.
[ServiceContract]
public interface IMenuService
{
[OperationContract]
[WebInvoke(Method = "GET",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetMenuDetails/")]
List<MenuItem.MenuDetailDataContract>
GetMenuDetails();
}
}

Image 15.
Now
open MenuService.svc:
using System;
using
System.Collections.Generic;
using System.Linq;
using
System.Runtime.Serialization;
using
System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace
DynamicMenu_MVC_AngularJS_WCFService
{
// NOTE: You can use the
"Rename" command on the "Refactor" menu to change the class
name "MenuService" in code, svc and config file together.
// 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.
public class MenuService : IMenuService
{
DynamicMenu_MVC_AngularJS_WCFService.TestDBEntities1 OME;
public MenuService()
{
OME = new
DynamicMenu_MVC_AngularJS_WCFService.TestDBEntities1();
}
public List<MenuItem.MenuDetailDataContract>
GetMenuDetails()
{
var query = (from A in OME.Menu
select new
{
A.Menu_ID,
A.Menu_Parent_ID,
A.Menu_Name,
A.ActionMethodName,
A.ControllerName
}).ToList();
List<MenuItem.MenuDetailDataContract> MenuList = new List<MenuItem.MenuDetailDataContract>();
query.ToList().ForEach(rec =>
{
MenuList.Add(new MenuItem.MenuDetailDataContract
{
Menu_ID = Convert.ToString(rec.Menu_ID),
Menu_Parent_ID =
rec.Menu_Parent_ID.ToString(),
Menu_Name = rec.Menu_Name.ToString(),
ActionMethodName =
rec.ActionMethodName,
ControllerName =
rec.ControllerName
});
});
return MenuList;
}
}
}

Image 16.
Make sure youe WCF Service web.config file should have
<ServiceModel> like below:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata
information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<!-- To receive exception details
in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information
-->
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior>
<webHttp helpEnabled="True" />
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="webHttpBinding" scheme="http" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

Image 17.
Now build your WCF Service.
Now time to add a new MVC project. So Rights click on
your project solution explorer -> Add -> New Project.

Image 18.

Image 19.

Image 20.
Now Add your WCF Service reference in your MVC project : Step To Add WCF Service
Reference.
- Run your WCF Service.
- Copy WCF Service URL
- Right Click on MVC projrct's -> Add
ServiceReference.

Image 21.

Image 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
-> ManageNuGet -> Search Angular:

Image 23.
Now time to add AngularJS Module.js, Controller.js
& Service.js.
So Create a New Folder iside : MVC Project->
Scripts-> MyScripts
Here add these 3 js File like below:
1.
Module.js
///
<reference path="../angular.js" />
///
<reference path="../angular.min.js" />
var app;
(function () {
app = angular.module("RESTClientModule", []);
})();

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

Image 25.
3.
Controller.js
/// <reference
path="../angular.js" />
/// <reference
path="../angular.min.js" />
/// <reference
path="Modules.js" />
/// <reference
path="Services.js" />
app.controller("MVCDynamicMenuWCF_Controller", function ($scope, $window,
AngularJs_WCFService) {
$scope.date = new Date();
$scope.showDetails = false;
getAllMenuDetails();
function getAllMenuDetails() {
var promiseGet =
AngularJs_WCFService.geMenuDetails();
promiseGet.then(function (pl) {
$scope.MenuDetailsDisp = pl.data
},
function (errorPl) {
});
}
$scope.showMenu = function (showMenus) {
if (showMenus == 1) {
$scope.showDetails = true;
}
else {
$scope.showDetails = false;
}
}
$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;
}
}
});

Image 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 -> Index.cshtml
So
My Index.cshtml is:
<style>
ul, li {
list-style-type: none;
margin: 0;
padding: 0;
}
.menu {
background: blue;
height: 5px;
color: #FFFFFF;
}
.menu > li {
display: inline-block;
padding: 2px 6px 22px 2px;
display: inline-block;
text-align: center;
height: 10px;
width: 176px;
color: #0094ff;
background: #0094ff;
}
.menu > li a {
display: inline-block;
padding: 2px 6px 22px 2px;
display: inline-block;
text-align: center;
height: 10px;
width: 176px;
color: #FFFFFF;
background: green;
}
.menu > li a:hover {
display: inline-block;
padding: 2px 6px 22px 2px;
display: inline-block;
text-align: center;
height: 10px;
width: 176px;
color: #000000;
background: yellow;
}
.sub-menu {
position: absolute;
display: none;
background-color: transparent;
padding: 5px;
}
.sub-menu > li {
display: block;
cursor: pointer;
}
.sub-menu > li a:hover {
display: block;
cursor: pointer;
background: yellow;
}
li:hover .sub-menu {
display: block;
}
</style>
<html data-ng-app="RESTClientModule">
@{
ViewBag.Title = "MVC- Dynamic
Menu using WCF REST & AngularJS";
}
<body data-ng-controller="MVCDynamicMenuWCF_Controller">
<div class="navbar navbar-inverse
navbar-fixed-top">
<div class="container">
<div class="navbar-collapse collapse">
<div style="overflow: visible;">
<ul class="menu">
<li data-ng-repeat="menus in
MenuDetailsDisp | filter:{Menu_Parent_ID:'0'}">
@{
var url = Url.Action("{{menus.ActionMethodName}}", "{{menus.ControllerName}}", new { id = "{{id=menus.ActionMethodName}}" });
url = HttpUtility.UrlDecode(url);
}
<a data-ng-href="@url">{{menus.Menu_Name}}</a>
<ul class="sub-menu">
<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);">
@{
var url1 = Url.Action("{{submenus.ActionMethodName}}", "{{submenus.ControllerName}}",
new { id = "{{id=submenus.ActionMethodName}}" });
url1 = HttpUtility.UrlDecode(url1);
}
<a data-ng-href="@url1">{{submenus.Menu_Name}}</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
<div style="height: 200px;"></div>
</body>
</html>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/MyScripts/Modules.js"></script>
<script src="~/Scripts/MyScripts/Services.js"></script>
<script
src="~/Scripts/MyScripts/controller.js"></script>
Now Run your application:

Image 27.

Image 28.

Image 29.

Image 30.

Image 31.

Image 32.