Bind Menu And Sub Menu Dynamically In ASP.NET MVC From Database Using LINQ

Introduction

Many times we need to create a menu for a simple application. We ususally get stuck on how to bind the menu. Here in this article we you will learn how to bind menu and sub menu dynamically in ASP.NET MVC from database using linq.

Step 1

I am going to create a database which contains the following fields as well as some dummy data which contains parent & child relationship.
Use the below script to create table & insert query, 
  1. USE [Dynamic_Menu]  
  2. GO  
  3. SET ANSI_NULLS ON  
  4. GO  
  5. SET QUOTED_IDENTIFIER ON  
  6. GO  
  7. SET ANSI_PADDING ON  
  8. GO  
  9. CREATE TABLE [dbo].[Menu_List](  
  10.     [M_ID] [int] IDENTITY(1,1) NOT NULL,  
  11.     [M_P_ID] [int] NULL,  
  12.     [M_NAME] [varchar](50) NULL,  
  13.     [CONTROLLER_NAME] [varchar](50) NULL,  
  14.     [ACTION_NAME] [varchar](50) NULL,  
  15.  CONSTRAINT [PK_Menu_List] PRIMARY KEY CLUSTERED   
  16. (  
  17.     [M_ID] ASC  
  18. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]  
  19. ) ON [PRIMARY]  
  20. GO  
  21. SET ANSI_PADDING OFF  
  22. GO  
  23. SET IDENTITY_INSERT [dbo].[Menu_List] ON  
  24. INSERT [dbo].[Menu_List] ([M_ID], [M_P_ID], [M_NAME], [CONTROLLER_NAME], [ACTION_NAME]) VALUES (1, 0, N'My Menu', NULL, NULL)  
  25. INSERT [dbo].[Menu_List] ([M_ID], [M_P_ID], [M_NAME], [CONTROLLER_NAME], [ACTION_NAME]) VALUES (2, 1, N'BCS', N'Menu', N'BCS_Action')  
  26. INSERT [dbo].[Menu_List] ([M_ID], [M_P_ID], [M_NAME], [CONTROLLER_NAME], [ACTION_NAME]) VALUES (3, 2, N'Computer', N'Menu', N'Computer_Action')  
  27. INSERT [dbo].[Menu_List] ([M_ID], [M_P_ID], [M_NAME], [CONTROLLER_NAME], [ACTION_NAME]) VALUES (4, 1, N'MCS', N'Menu', N'MCS_Action')  
  28. INSERT [dbo].[Menu_List] ([M_ID], [M_P_ID], [M_NAME], [CONTROLLER_NAME], [ACTION_NAME]) VALUES (5, 2, N'Maths', N'Menu', N'Maths_Action')  
  29. INSERT [dbo].[Menu_List] ([M_ID], [M_P_ID], [M_NAME], [CONTROLLER_NAME], [ACTION_NAME]) VALUES (6, 4, N'Marketing', N'Menu', N'Marketing_Action')  
  30. INSERT [dbo].[Menu_List] ([M_ID], [M_P_ID], [M_NAME], [CONTROLLER_NAME], [ACTION_NAME]) VALUES (7, 4, N'Finiance', N'Menu', N'Finiance_Action')  
  31. SET IDENTITY_INSERT [dbo].[Menu_List] OFF 
Step 2

Now create simple MVC appliation using visual studio. After creating project add edmx file by right clicking on project go to Add => New Item => (from right side templates) select Data => Select ADO.NET Entity Data Model => Give proper name to it and click on add button.

Then select your table from database & create .edmx file into your ptoject. After adding the file autmatically connection string will get added into web config file. 

 
Step 3

Now create model as below and add some properties; this model will be used into a controller & view.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5.   
  6. namespace Dynamic_Menu.Models  
  7. {  
  8.     public class Menu_List  
  9.     {  
  10.         public int M_ID { getset; }  
  11.         public int? M_P_ID { getset; }  
  12.         public string M_NAME { getset; }  
  13.         public string CONTROLLER_NAME { getset; }  
  14.         public string ACTION_NAME { getset; }  
  15.     }  
  16. }  
Step 4

Now add controller into our application and write below code into it. From action method GetMenuList() we will get data from our database using linq query.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6.   
  7. namespace Dynamic_Menu.Controllers  
  8. {  
  9.     public class HomeController : Controller  
  10.     {  
  11.         MenuEntities objEntity = new MenuEntities();  
  12.         public ActionResult Index()  
  13.         {  
  14.             return View();          
  15.         }  
  16.         public ActionResult GetMenuList()  
  17.         {  
  18.             try  
  19.             {  
  20.                 var result = (from m in objEntity.Menu_Tree  
  21.                               select new Dynamic_Menu.Models.Menu_List  
  22.                               {  
  23.                                   M_ID = m.M_ID,  
  24.                                   M_P_ID = m.M_P_ID,  
  25.                                   M_NAME = m.M_NAME,  
  26.                   CONTROLLER_NAME = CONTROLLER_NAME,  
  27.                                   ACTION_NAME = ACTION_NAME,  
  28.                               }).ToList();  
  29.                 return View("Menu", result);  
  30.             }  
  31.             catch (Exception ex)  
  32.             {  
  33.                 var error = ex.Message.ToString();  
  34.                 return Content("Error");  
  35.             }   
  36.         }  
  37.     }  

Step 5

Now create a view for Index action method as like.
  1. @{  
  2.     ViewBag.Title = "Index";  
  3.     Layout = "~/Views/Shared/_Layout.cshtml";  
  4. }  
  5.   
  6. <h2>Index</h2> 
Now create layout view for our application. Also create one partial view (name Menu.cshtml) as brlow,  which will render menu tree list when we are going to call action method from our layout page. In this partial view we are getting data into a IEnumerable list format and we are applying some logic as below,

Note

This is just demo / sample application, according to your requirement you can add foreach loop for more hierarchy levels. This is only a two level menu tree strucure.

_Layout.cshtml  => 
  1. <!DOCTYPE html>  
  2.   
  3. <html>  
  4. <head>  
  5.     <meta name="viewport" content="width=device-width" />  
  6.     <title>@ViewBag.Title</title>  
  7.     @Html.Action("GetMenuList", "Home")  
  8. </head>  
  9. <body>  
  10.     <div>  
  11.         @RenderBody()  
  12.     </div>  
  13. </body>  
  14. </html> 
 Menu.cshtml =>
  1. @model IEnumerable<Dynamic_Menu.Models.Menu_List>  
  2. <div>  
  3.     <ul>  
  4.         @{foreach (var item in Model.Where(s => s.M_P_ID == 0).GroupBy(Obj => new { Obj.M_ID }).Distinct().ToList())  
  5.         {  
  6.             <li>  
  7.                 <a href="#">  
  8.                     @item.FirstOrDefault().M_NAME  
  9.                 </a>  
  10.                 <ul>  
  11.                     @{foreach (var firstItem in (Model.Where(s => s.M_P_ID == item.FirstOrDefault().M_ID).ToList()))  
  12.                     {  
  13.                         <li>  
  14.                             <a href="#">  
  15.                                 @firstItem.M_NAME  
  16.                             </a>  
  17.                             <ul>  
  18.                                 @foreach (var secondItem in (Model.Where(s => s.M_P_ID == firstItem.M_ID).ToList()))  
  19.                                 {  
  20.                                     <li>  
  21.                                         <a href="/@secondItem.CONTROLLER_NAME/@secondItem.ACTION_NAME">  
  22.                                             @secondItem.M_NAME  
  23.                                         </a>  
  24.   
  25.                                     </li>  
  26.                                 }  
  27.                             </ul>  
  28.   
  29.                         </li>  
  30.                     }  
  31.                     }  
  32.                 </ul>  
  33.             </li>  
  34.         }  
  35.         }  
  36.     </ul>  
  37. </div>  
Step 5

Now create another controller to render views whenever we are clicking on hyper links from menu, it will redirect to that view by using controller name & action name
  1. namespace Dynamic_Menu.Controllers  
  2. {  
  3.     public class MenuController : Controller  
  4.     {  
  5. public ActionResult Computer_Action()  
  6.         {  
  7.             return View();  
  8.         }  
  9.         public ActionResult Maths_Action()  
  10.         {  
  11.             return View();  
  12.         }  
  13.         public ActionResult Marketing_Action()  
  14.         {  
  15.             return View();  
  16.         }  
  17.         public ActionResult Finiance_Action()  
  18.         {  
  19.             return View();  
  20.         }  
  21.   
  22.  }  

Create some views for above action as like
 
View For Computer_Action as,
  1. @{  
  2.     Layout = "~/Views/Shared/_Layout.cshtml";  
  3. }  
  4.   
  5. <!DOCTYPE html>  
  6.   
  7. <html>  
  8. <head>  
  9.     <meta name="viewport" content="width=device-width" />  
  10.     <title>Computer_Action</title>  
  11. </head>  
  12. <body>  
  13.     <div>   
  14.         <h2>Welcome To Computer View</h2>  
  15.     </div>  
  16. </body>  
  17. </html> 
 View For MCS_Action as
  1. @{  
  2.     Layout = "~/Views/Shared/_Layout.cshtml";  
  3. }  
  4.   
  5. <!DOCTYPE html>  
  6.   
  7. <html>  
  8. <head>  
  9.     <meta name="viewport" content="width=device-width" />  
  10.     <title>MCS_Action</title>  
  11. </head>  
  12. <body>  
  13.     <div>   
  14.         <h2>Welcome To MCS View</h2>  
  15.     </div>  
  16. </body>  
  17. </html>  
Step 6

Now run the application.

Index view after running the application into a browser.


If we click on menu   then our output will be:
 
 
Summary

In this article, you learned how to bind menu and sub menu dynamically in ASP.NET MVC from database using linq.