AngularJS Dynamic Menu Creation Using MVC and WCF Rest

Introduction

You can also view my previous articles related to AngularJS using MVC and WCF Rest Service.

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 and a user.

When an Admin is logged in he can add a new menu, edit an existing menu and delete a menu item to be displayed.

This article is not focused on menu management but in this article we will see in detail how to create a Menu Master and Menu Detail Table. Insert a sample Menu Item to our Database Tables. Display the Menu from the database dynamically to our MVC Web page using AngularJS and WCF Rest Service. This article will explain:

  1. How to create a WCF Rest service and retrieve data from a database.
  2. How to install the AngularJS Package into a MVC application.
  3. How to create our AngularJS application for Dynamic Menu Creation.
  4. How to use a WCS service in AngularJS to display dynamic Menu.

Note: the prerequisites are Visual Studio 2013 (if you don't have Visual Studio 2013, you can download it from Microsoft.

Here we can see some basics and reference links for Windows Communication Foundation (WCF). WCF is a framework for building service-oriented applications.

Service-oriented application:
Using this protocol the service can be shared and used over a network.

For example, let's consider that we are now working on a project and we need to create some common database function and those functions need to be used in multiple projects and the projects are in multiple places and connected via a network such as the internet.

In this case we can create a WCF service and we can write all our common database functions in our WCF service class. We can deploy our WCF in IIS and use the URL in our application to do DB functions. In the code part let's see how to create a WCF REST service and use it in our AngularJS application.

If you are interested in reading more details about WCF then kindly go to this link.

AngularJS

We might be be familiar with what Model, View and View Model (MVVM) is and what Model, View and Controller (MVC) is. AngularJS is a JavaScript framework that is purely based on HTML, CSS and JavaScript.

Similar to the MVC and MVVM patterns AngularJS uses the Model, View and Whatever (MVW) pattern.

In our example I have used a Model, View and Service. In the code part let's see how to install and create AngularJS in our MVC application.

If you are interested in reading more details about AngularJS then kindly go to this link.

Code Part

Create Database and Table

We will create a
MenuMaster MenuDetails table under the Database MenuDB.

Note: The MenuMaster and MenuDetail are the important tables that will use to load our menu dynamically. We need to understand how to insert menu details to these tables to display our menu properly.

In this article I have displayed a 3-level hierarchical display of menus. Here you can see the 3-level hierarchical sample.

Here we can see that the first level of the hierarchy is the Inventory.

The 2nd level of the hierarchy is the Inventory Details.

The 3rd level of the hierarchy is the Finished Goods Receipt and Finished Goods Issue.

Now let's see how to create a table relationship to create the master and detail menus.

Menu Master Table

  • 1st Level hierarchy Insert

 

  1. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Root','Inventory','Shanu',getdate()-23)  

 

  • 2nd Level hierarchies Insert

 

  1. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Inventory','INV001','Shanu',getdate()-23)  

 

  • 3rd Level hierarchies Insert

 

  1. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('INV001','FG001','Shanu',getdate()-23)  
  2.   
  3. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('INV001','FG002','Shanu',getdate()-23)  

Here we can see the fields for the Menu Master. I have used the following fields:

Master Table Field Name

Details

Menu_RootID

For every top level 1st hierarchy I will insert the id as "Root". This value will be used in a MVC angular filter to display only the 1st level menu items by default.

If there are 2-level or 3-level hierarchies tehn the master child id will be the RootID.

Menu_ChildID

Actual ID for each Menu Item.

UserID

This is optional. In your case you can store the user id or role id here to maintain the user management to display the menu.

CreatedDate

This is the record insert date.

Menu Detail Table

  • 1st Level hierarchy Insert
  1. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,  
  2. MenuURL,UserID,CreatedDate)  
  3. values('Inventory','Inventory','Inventory','Index','Inventory',  
  4. 'Shanu',getdate()-23)  
  • 2nd Level hierarchies Insert
  1. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,  
  2. MenuURL,UserID,CreatedDate)  
  3. values('INV001','Inventory','Inventory Details','Index','Inventory',  
  4. 'Shanu',getdate()-23)  
  • 3rd Level hierarchies Insert
  1. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,  
  2. MenuURL,UserID,CreatedDate)  
  3. values('FG001','FGIN','FG Receipt','FGIN','Inventory','Shanu',getdate()-43)  
  4. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,  
  5. MenuURL,UserID,CreatedDate)  
  6. values('FG002','FGOUT','FG Issue','FGOUT','Inventory','Shanu',getdate()-13)  

Here we can see the field for the Menu Detail. I have used the following fields.

Master Table Field Name

Details

Menu_ChildID

Here we will insert the same Menu Master Child ID

MenuName

This is to provide a Name for every Menu Item.

MenuDisplayTxt

Menu Display Text. This field will be used to display in our menu.

MenuFileName

This is our actual File name for each menu. Here I have used the MVC so I will provide only the File name as our View name.

MenuURL

The URL path for each Menu item to be used for the hyperlink. Here in my example it was developed using MVC so I will provide the URL as the Controller name. Suppose you are using the ASP.Net web site then you can provide the URL as:

“/yourFolderName/yourfilename.aspx”

UserID

This is optional. In your case you can store a user id or role id here to maintain the user management to display the menu.

CreatedDate

This is the record insert date.

The following is the script to create a database, table and sample insert query. Run this script in your SQL Server. I have used SQL Server 2012.

  1. -- =============================================                                  
  2. -- Author      : Shanu                                  
  3. -- Create date : 2015-03-20                                  
  4. -- Description : To Create Database,Table and Sample Insert Query                               
  5. -- Latest                                  
  6. -- Modifier    : Shanu                                  
  7. -- Modify date : 2015-03-20                              
  8. -- =============================================  
  9. --Script to create DB,Table and sample Insert data  
  10. USE MASTER  
  11. GO  
  12. -- 1) Check for the Database Exists .If the database is exist then drop and create new DB  
  13. IF EXISTS (SELECT [nameFROM sys.databases WHERE [name] = 'MenuDB' )  
  14. DROP DATABASE MenuDB  
  15. GO  
  16.   
  17. CREATE DATABASE MenuDB  
  18. GO  
  19.   
  20. USE MenuDB  
  21. GO  
  22.   
  23. -- 1) //////////// ToysDetails table  
  24. -- Create Table  ToysDetails ,This table will be used to store the details like Toys Information   
  25.   
  26. IF EXISTS ( SELECT [nameFROM sys.tables WHERE [name] = 'MenuMaster' )  
  27. DROP TABLE MenuMaster  
  28. GO  
  29.   
  30. CREATE TABLE MenuMaster  
  31. (  
  32.    Menu_ID int identity(1,1),  
  33.    Menu_RootID VARCHAR(30)  NOT NULL,  
  34.    Menu_ChildID VARCHAR(30)  NOT NULL,  
  35.    UserID varchar(50),  
  36.    CreatedDate datetime  
  37. CONSTRAINT [PK_MenuMaster] PRIMARY KEY CLUSTERED        
  38. (       
  39.   [Menu_ID] ASC   ,  
  40.   [Menu_RootID] ASC,  
  41.   [Menu_ChildID] ASC    
  42. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]       
  43. ON [PRIMARY]     
  44.   
  45. GO  
  46. --delete from MenuMaster  
  47. -- Insert the sample records to the ToysDetails Table  
  48. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Root','Home','Shanu',getdate()-23)  
  49. --Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Home','Home','Shanu',getdate()-23)  
  50. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Home','About','Shanu',getdate()-23)  
  51. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Home','Contact','Shanu',getdate()-23)  
  52.   
  53. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Root','Masters','Shanu',getdate()-23)  
  54. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Masters','ITM001','Shanu',getdate()-23)  
  55. --Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('ITM001','ITM001','Shanu',getdate()-23)  
  56. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('ITM001','ITM002','Shanu',getdate()-23)  
  57. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('ITM001','ITM003','Shanu',getdate()-23)  
  58. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Masters','CAT001','Shanu',getdate()-23)  
  59. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('CAT001','CAT001','Shanu',getdate()-23)  
  60. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('CAT001','CAT002','Shanu',getdate()-23)  
  61. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('CAT001','CAT003','Shanu',getdate()-23)  
  62.   
  63.   
  64. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Root','Inventory','Shanu',getdate()-23)  
  65. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('Inventory','INV001','Shanu',getdate()-23)  
  66. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('INV001','FG001','Shanu',getdate()-23)  
  67. Insert into MenuMaster(Menu_RootID,Menu_ChildID,UserID,CreatedDate) values('INV001','FG002','Shanu',getdate()-23)  
  68.   
  69.   
  70.   
  71. select * from MenuMaster  
  72. -- 1) END //  
  73.   
  74. -- 2) Cart Details Table  
  75. IF EXISTS ( SELECT [nameFROM sys.tables WHERE [name] = 'MenuDetails' )  
  76. DROP TABLE MenuDetails  
  77. GO  
  78.   
  79. CREATE TABLE MenuDetails  
  80. (  
  81.    MDetail_ID int identity(1,1),  
  82.    Menu_ChildID VARCHAR(20) NOT NULL,  
  83.    MenuName VARCHAR(100) NOT NULL,  
  84.    MenuDisplayTxt VARCHAR(200) NOT NULL,  
  85.    MenuFileName VARCHAR(100) NOT NULL,   
  86.    MenuURL VARCHAR(500) NOT NULL,  
  87.    USE_YN Char(1) DEFAULT 'Y',  
  88.    UserID varchar(50),  
  89.    CreatedDate datetime  
  90. CONSTRAINT [PK_MenuDetails] PRIMARY KEY CLUSTERED        
  91. (       
  92.   [MDetail_ID] ASC,  
  93.   [Menu_ChildID] ASC         
  94. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]       
  95. ON [PRIMARY]     
  96.   
  97. GO  
  98. ----delete from MenuDetails  
  99.   
  100. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  101. values('Root','Home','Shanu Home','Index','Home','Shanu',getdate()-23)  
  102.   
  103. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  104. values('Home','Home','Shanu Home','Index','Home','Shanu',getdate()-23)  
  105.   
  106. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  107. values('About','About','About Shanu','About','Home','Shanu',getdate()-43)  
  108.   
  109. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  110. values('Contact','Contact','Contact Shanu','Contact','Home','Shanu',getdate()-13)  
  111.   
  112. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  113. values('Masters','Masters','Masters','ItemDetails','Masters','Shanu',getdate()-13)  
  114.   
  115. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  116. values('ITM001','ItemMaster','Item Master','ItemDetails','Masters','Shanu',getdate()-13)  
  117.   
  118. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  119. values('ITM002','ItemDetail','Item Details','ItemDetails','Masters','Shanu',getdate()-13)  
  120.   
  121. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  122. values('ITM003','ItemManage','Item Manage','ItemManage','Masters','Shanu',getdate()-13)  
  123.   
  124.   
  125.   
  126. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  127. values('CAT001','CatMaster','Category Masters','CATDetails','Masters','Shanu',getdate()-13)  
  128.   
  129. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  130. values('CAT002','CATDetail','Category Details','CATDetails','Masters','Shanu',getdate()-13)  
  131.   
  132. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  133. values('CAT003','CATManage','Category Manage','CATManage','Masters','Shanu',getdate()-13)  
  134.   
  135.   
  136.   
  137. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  138. values('Inventory','Inventory','Inventory','Index','Inventory','Shanu',getdate()-23)  
  139.   
  140. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  141. values('INV001','Inventory','Inventory Details','Index','Inventory','Shanu',getdate()-23)  
  142.   
  143. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  144. values('FG001','FGIN','FG Receipt','FGIN','Inventory','Shanu',getdate()-43)  
  145.   
  146. Insert into MenuDetails(Menu_ChildID,MenuName,MenuDisplayTxt,MenuFileName,MenuURL,UserID,CreatedDate)   
  147. values('FG002','FGOUT','FG Issue','FGOUT','Inventory','Shanu',getdate()-13)  
  148.   
  149.   
  150. select * from MenuMaster  
  151.   
  152. select * from MenuDetails  
  153.   
  154.         select   A.Menu_RootID,  
  155.                  B.MDetail_ID,  
  156.                  B.Menu_ChildID,  
  157.                  B.MenuName,  
  158.                  B.MenuDisplayTxt,  
  159.                  B.MenuFileName,             
  160.                  B.MenuURL ,             
  161.                  B.UserID                                                        
  162.                  FROM   
  163.                  MenuMaster A  
  164.                  INNER JOIN MenuDetails B  
  165.                  ON A.Menu_ChildID=B.Menu_ChildID  
  • Create WCF REST Service

Open Visual Studio 2013 then select "File" -> "New" -> "Project..." then select WCF Service Application then select your project path and name your WCF service and click OK.

Once we have created the WCF Service we can see “IService.CS” and “Service1.svc” in the Solution Explorer as in the following.

  • IService.CS: In “IService.CS” we can see 3 contracts by default.
  • [ServiceContract]: Describes the methods or any operations available for the service. The Service Contract is an interface and methods can be declared inside the Service Interface using the Operation Contract attribute.
  • [OperationContract]: is similar to the web service [WEBMETHOD].
  • [DataContract]: describes the data exchange between the client and the service.
  • [ServiceContract]

The following code will be automatically created for all the IService.CS files. We can change and write our own code here.

  1. public interface IService1  
  2. {  
  3.   
  4.     [OperationContract]  
  5.     string GetData(int value);  
  6.   
  7.     [OperationContract]  
  8.     CompositeType GetDataUsingDataContract(CompositeType composite);  
  9.   
  10.     // TODO: Add your service operations here  
  11. }  
  12. // Use a data contract as illustrated in the sample below to add composite types to service operations.  
  13. [DataContract]  
  14. public class CompositeType  
  15. {  
  16.     bool boolValue = true;  
  17.     string stringValue = "Hello ";  
  18.   
  19.     [DataMember]  
  20.     public bool BoolValue  
  21.     {  
  22.         get { return boolValue; }  
  23.         set { boolValue = value; }  
  24.     }  
  25.   
  26.     [DataMember]  
  27.     public string StringValue  
  28.     {  
  29.         get { return stringValue; }  
  30.         set { stringValue = value; }  
  31.     }  
  32. }  
Data Contract In our example we need to get all the Menu Details from the database, so I have created the Data ContractsMenuDataContract”. Here we can see we have decelerated our entire table column name as Data Member.
  1. public class MenuDataContract  
  2.     {  
  3.         [DataContract]  
  4.         public class MenuMasterDataContract  
  5.         {  
  6.             [DataMember]  
  7.             public string Menu_ID { getset; }  
  8.   
  9.             [DataMember]  
  10.             public string Menu_RootID { getset; }  
  11.   
  12.             [DataMember]  
  13.             public string Menu_ChildID { getset; }  
  14.   
  15.             [DataMember]  
  16.             public string UserID { getset; }  
  17.   
  18.         }  
  19.   
  20.         [DataContract]  
  21.         public class MenuDetailDataContract  
  22.         {  
  23.             [DataMember]  
  24.             public string MDetail_ID { getset; }  
  25.   
  26.             [DataMember]  
  27.             public string Menu_RootID { getset; }  
  28.   
  29.             [DataMember]  
  30.             public string Menu_ChildID { getset; }  
  31.   
  32.             [DataMember]  
  33.             public string MenuName { getset; }  
  34.   
  35.             [DataMember]  
  36.             public string MenuDisplayTxt { getset; }  
  37.   
  38.             [DataMember]  
  39.             public string MenuFileName { getset; }  
  40.   
  41.             [DataMember]  
  42.             public string MenuURL { getset; }  
  43.   
  44.             [DataMember]  
  45.             public string UserID { getset; }  
  46.         }  
  47.   
  48.     }  
Service Contract: In the Operation Contract we can see “WebInvoke” and “WebGet” for retrieving the data from the database in the REST Serivce. 
  1. RequestFormat = WebMessageFormat.Json,  
  2. ResponseFormat = WebMessageFormat.Json,  
Here we can see both of the request and response formats. Here I have used the JavaScript Object Notation (JSON) format.
  • JSON is a lightweight data interchange format.
  • UriTemplate: Here we provide our Method Name.
Here I have declared the 3 methods “GetMenuDetails”. The “GetMenuDetails” method gets all the Menu Master and Details that will be used in our AngularJS to display the menu using a filter for each hierarchy.
  1. [ServiceContract]  
  2.     public interface IService1  
  3.     {  
  4. [OperationContract]  
  5.         [WebInvoke(Method = "GET",  
  6.            RequestFormat = WebMessageFormat.Json,  
  7.            ResponseFormat = WebMessageFormat.Json,  
  8.            UriTemplate = "/GetMenuDetails/")]  
  9.         List<MenuDataContract.MenuDetailDataContract> GetMenuDetails();  
  10.  }  
Add Database usingADO.NET Entity Data Model

Right-click your WCF project and select Add New Item then select ADO.NETEntity Data Model and click Add.


Select EF Designer from Database and click Next.

Click New Connection.

Here we can select our Database Server Name and enter the DB server SQL Server Authentication User ID and Password. We have already created our database as “MenuDB” so we can select the database and click OK.


Click Next and select the tables to be used and click Finish.

Here we can see we have now created our ShanuMenuModel.

Service1.SVC

“Service.SVC.CS” implements the IService Interface and overrides and defines all the methods of the Operation Contract. For example here we can see I have implemented the IService1 in the Service1 class. I have created the object for our Entity model and in GetMenuDetails using a LINQ join query I get both Menu Master and Detaildatas.

  1. public class Service1 : IService1  
  2.     {  
  3.         ShanuMenuCreation_WCF.MenuDBEntities OME;  
  4.   
  5.         public Service1()  
  6.         {  
  7.             OME = new ShanuMenuCreation_WCF.MenuDBEntities();  
  8.         }  
  9.   
  10.         public List<MenuDataContract.MenuDetailDataContract> GetMenuDetails()  
  11.         {  
  12.             ////var query = (from a in OME.MenuDetails  
  13.             ////             select a).Distinct();  
  14.              var query = (from A in OME.MenuMaster     
  15.                          join B in OME.MenuDetails on A.Menu_ChildID equals B.Menu_ChildID   
  16.                          select new     
  17.                          {     
  18.                             A.Menu_RootID,  
  19.                             B.MDetail_ID,  
  20.                             B.Menu_ChildID,  
  21.                             B.MenuName,  
  22.                             B.MenuDisplayTxt,  
  23.                             B.MenuFileName,  
  24.                             B.MenuURL ,  
  25.                             B.UserID  
  26.                          }).ToList().OrderBy(q => q.MDetail_ID);    
  27.   
  28.             List<MenuDataContract.MenuDetailDataContract> MenuList = new List<MenuDataContract.MenuDetailDataContract>();  
  29.   
  30.             query.ToList().ForEach(rec =>  
  31.             {  
  32.                 MenuList.Add(new MenuDataContract.MenuDetailDataContract  
  33.                 {  
  34.                     MDetail_ID = Convert.ToString(rec.MDetail_ID),  
  35.                     Menu_RootID = rec.Menu_RootID,  
  36.                     Menu_ChildID = rec.Menu_ChildID,  
  37.                     MenuName = rec.MenuName,  
  38.                     MenuDisplayTxt = rec.MenuDisplayTxt,  
  39.                     MenuFileName = rec.MenuFileName,  
  40.                     MenuURL = rec.MenuURL,  
  41.                     UserID = rec.UserID,  
  42.                 });  
  43.             });  
  44.             return MenuList;  
  45.         }        
  46.     }  

Web.Config

In the WCF project's “Web.Config” make the following changes.

Change

  1. <add binding="basicHttpsBinding" scheme="https" /> to <add binding="webHttpBinding" scheme="http" />  
Replace the behaviour as in the following:
  1. </behaviors>  
  2.    <endpointBehaviors>  
  3.         <behavior>  
  4.           <webHttp helpEnabled="True"/>  
  5.         </behavior>  
  6.     </endpointBehaviors>  
  7. </behaviors>  
Run WCF Service: Now that we have created our WCF Rest service, let's run and test our service. In our service URL we can add our method name and we can see the JSON result data from the database.

Create MVC Web Application

So now we have completed our WCF and now it's time to create our MVC AngularJS application.

We can add a new project to our existing project and create a new MVC web application as in the following.

Right-click the project in the solution and click Add New Project then enter your project name and click "OK".

Select MVC and click "OK".

We have now created our MVC application and it's time to add our WCF Service and install the AngularJS package to our solution.

Add WCF Service: Right-click MVC Solution and click Add then click Service Reference.

Enter your WCF URL and click GO. Here my WCF URL is http://localhost:3514/Service1.svc/

Add your name and click OK.

Now we have successfully added our WCF Service to our MVC application.

Procedure to Install AngularJS package

Right-click your MVC project and click Manage NuGet Packages.



Select Online and Search for AngularJS. Select the AngularJS and click Install.



Now we have Installed the AngularJS package into our MVC Project. Now let's create our AngularJS.
  • Modules.js
  • shoppingController.js
  • Services.js

Procedure to Create AngularJS Script Files

Right-click the Script folder and create your own folder to create the AngularJS Model/Controller and Service JavaScript. In your script folder add three JavaScript files and name them Modules.js, Controllers.js and Services.js as in the following.

 
Modules.js: Here we add the reference to the Angular.js JavaScript. We provide the module name as “RESTClientModule.
  1. /// <reference path="../angular.js" />   
  2. /// <reference path="../angular.min.js" />     
  3.   
  4. var app;  
  5.   
  6. (function () {  
  7.     app = angular.module("RESTClientModule", []);  
  8. })();  

Services.js: Here we provide a name for our service and we use this name in shanucontroller.js. Here for the Angular service I have given the name "AngularJs_WCFService". You can provide your own name but be careful of changing the name in Controllers.js. AngularJS can receive JSON data. Here we can see I have provided our WCS service URL to get the Item details as JSON data. To insert an Item information result to the database we pass the data as JSON data to our WCFinsert method as a parameter.

  1. /// <reference path="../angular.js" />    
  2. /// <reference path="../angular.min.js" />     
  3.   
  4. /// <reference path="Modules.js" />     
  5.      
  6. app.service("AngularJs_WCFService"function ($http) {  
  7.     //Get Order Master Records    
  8.     this.geMenuDetails = function () {  
  9.         return $http.get("http://localhost:3514/Service1.svc/GetMenuDetails");  
  10.     };       
  11.   
  12. });  
AngularJS Controller: Here we add the reference to the Angular.js JavaScript, our Module.js and Services.js. The same as for services. For the controller I have given the name "AngularJsShanu_WCFController". In the Controller I have done all the business logic and returned the data from the WCF JSON data to our MVC HTML page.

Variable declarations

First I declared all the local variables that need to be used and the current date and store the date using $scope.date.

Note:
$scope.subChildIDS = "ITM001"; this variable has been used to filter the 2nd level hierarchy.

Methods

getAllMenuDetails(): In this method I will get all the Menu Detail as JSON and bind the result to the Main page.
 $scope.showsubMenu = function (showMenus,ids) {}
In this method on mouse hover I will filter the 2nd level hierarchy menu details and add the menu items to the list.

shanuController.js full source code

  1. /// <reference path="../angular.js" />    
  2. /// <reference path="../angular.min.js" />     
  3. /// <reference path="Modules.js" />     
  4. /// <reference path="Services.js" />     
  5.   
  6.   
  7. app.controller("AngularJsShanu_WCFController"function ($scope, $window, AngularJs_WCFService) {  
  8.     $scope.date = new Date();  
  9.   
  10.     $scope.showDetails = false;  
  11.     $scope.showSubDetails = false;  
  12.     $scope.subChildIDS = "ITM001";  
  13.     $scope.Imagename = "R1.png";  
  14.   
  15.     getAllMenuDetails();  
  16.     //To Get All Records     
  17.     function getAllMenuDetails() {  
  18.   
  19.         var promiseGet = AngularJs_WCFService.geMenuDetails();  
  20.         promiseGet.then(function (pl) {  
  21.             $scope.MenuDetailsDisp = pl.data  
  22.         },  
  23.              function (errorPl) {  
  24.   
  25.              });  
  26.     }  
  27.     
  28.     $scope.showMenu = function (showMenus) {  
  29.        
  30.         if (showMenus == 1) {  
  31.             $scope.Imagename = "R2.png"  
  32.             $scope.showDetails = true;  
  33.   
  34.         }  
  35.         else {  
  36.             $scope.Imagename = "R1.png"  
  37.             $scope.showDetails = false;  
  38.         }  
  39.     }  
  40.   
  41.     $scope.showsubMenu = function (showMenus,ids) {  
  42.         
  43.         if (showMenus == 1) {  
  44.             $scope.subChildIDS = ids;  
  45.            
  46.             $scope.showSubDetails = true;            
  47.         }  
  48.         else if(showMenus == 0) {  
  49.             $scope.showSubDetails = false;            
  50.         }       
  51.         else {  
  52.            
  53.             $scope.showSubDetails = true;  
  54.            
  55.         }         
  56.     }  
  57.   
  58. });  

So now we have created our AngularJS Module/Controller and Service. So what is next?

So now we have created our AngularJS Module, Controller and Service. So what is next?

Create MVC Controland View to display our result.

Add Controller

Right-click Controllers then select Add Controller then select MVC 5 Controller–Empty then click Add.

Change the Controller name and here I have given it the name “MastersController” and click OK.

Add View

Right-click on the Controller Index and click Add View.

MVC Controller CS File: Here we can in my MVC Controller, I have created 3 menus with sub items. For example I have created the 2 controllers MastersController.cs and InventoryController.cs.

  1. public class MastersController : Controller  
  2.     {  
  3.         // GET: Masters  
  4.         public ActionResult Index()  
  5.         { return View(); }  
  6.   
  7.   
  8.         public ActionResult ItemDetails()  
  9.         { return View(); }  
  10.   
  11.         public ActionResult ItemManage()  
  12.         { return View(); }  
  13.   
  14.         public ActionResult CATDetails()  
  15.         { return View(); }  
  16.   
  17.         public ActionResult CATManage()  
  18.         { return View(); }  
  19.     }  
Add one more controller as InventoryController.
  1. public class InventoryController : Controller  
  2.     {  
  3.         // GET: Inventory  
  4.         public ActionResult Index()  
  5.         {  
  6.             return View();  
  7.         }  
  8.   
  9.         public ActionResult FGIN()  
  10.         {   
  11.             return View();  
  12.         }  
  13.         public ActionResult FGOUT()  
  14.         {  
  15.             return View();  
  16.         }  
  17.     }  

Index View

Name the View “Index”.

In the View, design your page and reference angular.js, Modules.js, Services.js and Controllers.js.

In AngularJS we use {{ }} to bind or display the data.

Here we can see that I first created a table and something for that table.

First in the table I used the data-ng-controller="AngularJsShanu_WCFController" and here we can see data-ng-controller will be used to bind the data of the controller to the HTML table.

Using <
li data-ng-repeat="menus in MenuDetailsDisp | filter:{Menu_RootID:'Root'}" > we can get all the menu details and display the First Level hierarchy menu details as top menu.

Here we can see I have filtered the menu by the rootId "Root". During our insert query I have already explained that for every top-level menu I will provide the Rootid as ‘Root’. First we add all the top-level menus and for each top-level menu if there is any 2nd level hierarchy then I will load the 2nd level menu details to filter by the 1st level RootID as in the following.

  1. <li data-ng-repeat="menus in MenuDetailsDisp | filter:{Menu_RootID:'Root'}">  
  2.                                         @{  
  3.                                             var url = Url.Action("{{menus.MenuFileName}}", "{{menus.MenuURL}}", new { id = "{{id=menus.MenuURL}}" });  
  4.                                             url = HttpUtility.UrlDecode(url);  
  5.                                         }  
  6.                                         <a data-ng-href="@url">{{menus.MenuDisplayTxt}}</a>  
  7.   
  8.                                         <ul class="sub-menu">  
  9.                                             <li data-ng-repeat="submenus in MenuDetailsDisp | filter:{Menu_RootID:menus.Menu_ChildID}" ng-mouseover="showsubMenu(1,submenus.Menu_ChildID);" ng-mouseout="showsubMenu(0,submenus.Menu_ChildID);">  
  10.                                                 @{  
  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.MenuDisplayTxt}}</a>  
Here we can see for the 2nd level hierarchyI have filtered by data-ng-repeat="submenus in MenuDetailsDisp | filter :{Menu_RootID:menus.Menu_ChildID}" where menus.Menu_ChildID is the top-level menu id.

the same for the 3rdlevel hierarchy. I will provide the 2nd level hierarchy root id as in the following.
  1. <div style="overflow:visible;height:100px;">  
  2.                                 <ul class="menu">  
  3.                                     <li data-ng-repeat="menus in MenuDetailsDisp | filter:{Menu_RootID:'Root'}">  
  4.                                         @{  
  5.                                             var url = Url.Action("{{menus.MenuFileName}}", "{{menus.MenuURL}}", new { id = "{{id=menus.MenuURL}}" });  
  6.                                             url = HttpUtility.UrlDecode(url);  
  7.                                         }  
  8.                                         <a data-ng-href="@url">{{menus.MenuDisplayTxt}}</a>  
  9.   
  10.                                         <ul class="sub-menu">  
  11.                                             <li data-ng-repeat="submenus in MenuDetailsDisp | filter:{Menu_RootID:menus.Menu_ChildID}" ng-mouseover="showsubMenu(1,submenus.Menu_ChildID);" ng-mouseout="showsubMenu(0,submenus.Menu_ChildID);">  
  12.                                                 @{  
  13.                                                     var url1 = Url.Action("{{submenus.MenuFileName}}", "{{submenus.MenuURL}}", new { id = "{{id=submenus.MenuURL}}" });  
  14.                                                     url1 = HttpUtility.UrlDecode(url1);  
  15.                                                 }  
  16.                                                 <a data-ng-href="@url1">{{submenus.MenuDisplayTxt}}</a>  
  17.   
  18.                                                 <ul ng-show="showSubDetails" class="sub-menu2">  
  19.                                                     <li data-ng-repeat="sub1menus in MenuDetailsDisp  | filter:{Menu_RootID:subChildIDS}" ng-mouseover="showsubMenu(3,9);">  
  20.                                                         @{  
  21.                                                             var url2 = Url.Action("{{sub1menus.MenuFileName}}", "{{sub1menus.MenuURL}}", new { id = "{{id=sub1menus.MenuURL}}" });  
  22.                                                             url2 = HttpUtility.UrlDecode(url2);  
  23.                                                         }  
  24.                                                         <a data-ng-href="@url2">{{sub1menus.MenuDisplayTxt}}</a>  
  25.                                                     </li>  
  26.                                                 </ul>  
  27.   
  28.                                             </li>  
  29.                                         </ul>  
  30.   
  31.                                     </li>  
  32.                                 </ul>  
  33.   
  34.                             </div>  

Run the Program

(Output Menu Type 1)

(Output Menu Type 2)

 

Note: This code can be used in our MVC View page or this code can be used in Shared>Layout.Cshtml so that the menu will be a common menu that can be used for all pages globally. Here we can see in the preceding that the same menu code has been added to the Layout.cshtm page. By this the menu will be added globally and can be accessed in all pages.

You can extend this application depending on your requirements and add more functionality, like user management, menu management and and so on.

Supported Browsers: Chrome and Firefox.