In this article, we will create a dynamic tree view menu fetched from the database, using ASP.NET MVC 5, C#, Razor and SQL Server 2014 (using Visual Studio 2013). This article will guide you on how to display parent child tree view dynamically from the database. This is the best, easiest, and fastest way to make tree view. Let's try to populate it.
Step 1

Create table query
- CREATE TABLE [dbo].[Categories](
- [CategoryId] [int] primary key identity(1,1),
- [CategoryName] [varchar](40),
- [ParentCategoryId] [int],
- [Remarks] [nvarchar](max),
- )
Step 2
Step 3
Create a new project and take Empty ASP.NET MVC Application. Here, I have used MVC 5 project.
Step 4
Add new Class Library Project. The solution is named Business Layer which contains an actual logic and an interaction with the database.
Step 5
Add new class named SqlAccess in BusinessLayer project. The class has a constructor to initialize SqlConnection and a method, which will take query in the string format and return rows in DataTable.
- #region Declaration
- SqlConnection con;
- DataTable dt;
- #endregion
- #region Constructor
- public SqlAccess()
- {
- con = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["ConStr"]);
- }
- #endregion
- #region KeyMethods
- public DataTable GetDataTableFromDb(string query)
- {
- SqlDataAdapter Adpt = new SqlDataAdapter(query, con);
- dt = new DataTable();
- try
- {
- Adpt.Fill(dt);
- }
- catch (SqlException ex)
- {
- dt = null;
- if (con.State == ConnectionState.Open)
- con.Close();
- }
- finally
- {
- if (con != null)
- if (con.State == ConnectionState.Open) con.Close();
- Adpt.Dispose();
- }
- return dt;
- }
- #endregion
Step 6
Add another class named HomeBAL in BusinessLayer. This class contains a method that passes query to SqlAccess and returns the DataTable.
- public DataTable GetAllCategories()
- {
- return new SqlAccess().GetDataTableFromDb("SELECT CategoryId, CategoryName, ParentCategoryId FROM Categories");
- }
Step 7
Now, we need to access BusinessLayer members from our PresentationLayer (MVC Project). So, give the referenc of BusinessLayer to PresentationLayer.
Step 8
Add a new class named Category in PresentationLayer, which contains database structure properties.- public class Category
- {
- public int CategoryId { get; set; }
- public string CategoryName { get; set; }
- public System.Nullable<int> ParentCategoryId { get; set; }
- }
Step 9
Add a new class named TreeNode in “PresentationLayer” which contains database properties, and add one more List<> type of property which will hold all the children of the particular category.- public class TreeNode
- {
- public int CategoryId { get; set; }
- public string CategoryName { get; set; }
- public TreeNode ParentCategory { get; set; }
- public List<TreeNode> Children { get; set; }
- }
Step 10
Add a new Controller named “HomeController” which has one action method (Index) and two other methods.Index Action Method
- public ActionResult Index()
- {
- ViewBag.Tree = GetAllCategoriesForTree();
- return View();
- }
Recursive method
- private static List<TreeNode> FillRecursive(List<Category> flatObjects, int? parentId = null)
- {
- return flatObjects.Where(x => x.ParentCategoryId.Equals(parentId)).Select(item => new TreeNode
- {
- CategoryName = item.CategoryName,
- CategoryId = item.CategoryId,
- Children = FillRecursive(flatObjects, item.CategoryId)
- }).ToList();
- }
Get all categories from database and generate html string,
- public string GetAllCategoriesForTree()
- {
- List<Category> categories = new List<Category>();
- DataTable dt = new HomeBAL().GetAllCategories();
- if (dt != null && dt.Rows.Count > 0)
- {
- foreach (DataRow row in dt.Rows)
- {
- categories.Add(
- new Category
- {
- CategoryId = Convert.ToInt32(row["CategoryId"]),
- CategoryName = row["CategoryName"].ToString(),
- ParentCategoryId = (Convert.ToInt32(row["ParentCategoryId"]) != 0) ? Convert.ToInt32(row["ParentCategoryId"]) : (int?) null
- });
- }
- List<TreeNode> headerTree = FillRecursive(categories, null);
- #region BindingHeaderMenus
- string root_li = string.Empty;
- string down1_names = string.Empty;
- string down2_names = string.Empty;
- foreach (var item in headerTree)
- {
- root_li += "<li class=\"dropdown mega-menu-fullwidth\">"
- + "<a href=\"/Product/ListProduct?cat=" + item.CategoryId + "\" class=\"dropdown-toggle\" data-hover=\"dropdown\" data-toggle=\"dropdown\">" + item.CategoryName + "</a>";
- down1_names = "";
- foreach (var down1 in item.Children)
- {
- down2_names = "";
- foreach (var down2 in down1.Children)
- {
- down2_names += "<li><a href=\"/Product/ListProduct?cat=" + down2.CategoryId + "\">" + down2.CategoryName + "</a></li>";
- }
- down1_names += "<div class=\"col-md-2 col-sm-6\">"
- + "<h3 class=\"mega-menu-heading\"><a href=\"/Product/ListProduct?cat=" + down1.CategoryId + "\">" + down1.CategoryName + "</a></h3>"
- + "<ul class=\"list-unstyled style-list\">"
- + down2_names
- + "</ul>"
- + "</div>";
- }
- root_li += "<ul class=\"dropdown-menu\">"
- + "<li>"
- + "<div class=\"mega-menu-content\">"
- + "<div class=\"container\">"
- + "<div class=\"row\">"
- + down1_names
- + "</div>"
- + "</div>"
- + "<div>"
- + "</li>"
- + "</ul>"
- + "</li>";
- }
- #endregion
- return "<ul class=\"nav navbar-nav\">" + root_li + "</ul>";
- }
- return "Record Not Found!!";
- }
Step 11
Add new View named “Index.cshtml” which contains our webpage's body and displays the viewbag return from Controller.- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>Dynamic Tree</title>
- </head>
- <body>
- <div class="header-v5 header-static">
- <!-- Navbar -->
- <div class="navbar navbar-default mega-menu" role="navigation">
- <div class="container">
- <div class="collapse navbar-collapse navbar-responsive-collapse">
- @Html.Raw(ViewBag.Tree);
- </div>
- </div>
- </div>
- <!-- End Navbar -->
- </div>
- </body>
- </html>
Step 12
If you run this action, your tree is ready but without design, as shown below.Step 13
Put the CSS content inside project and include it in page. You can see successfully generated TreeView like below.
Final Output
Thank you developers… I have attached the full project with this article. Please comment if you encounter any issues here.
Note
Here, I am showing you two queries which are getting all categories from db.
Simple Parent Child
- SELECT
- CategoryId,
- CategoryName,
- ParentCategoryId
- FROM
- Categories
If you want TreeView from SQL query,
- SELECT
- CASE
- WHEN
- down1.CategoryName is null
- THEN
- root.CategoryId
- WHEN
- down2.CategoryName is null
- THEN
- down1.CategoryId
- WHEN
- down3.CategoryName is null
- THEN
- down2.CategoryId
- ELSE
- 0
- END AS CategoryId
- ,root.CategoryName as root_name
- ,ISNULL(down1.CategoryName,'') as down1_name
- ,ISNULL(down2.CategoryName,'') as down2_name
- ,ISNULL(down3.CategoryName,'') as down3_name
- FROM Categories as root
- LEFT OUTER
- JOIN Categories AS down1
- ON down1.ParentCategoryId = root.CategoryId
- LEFT OUTER
- JOIN Categories AS down2
- ON down2.ParentCategoryId = down1.CategoryId
- LEFT OUTER
- JOIN Categories AS down3
- ON down3.ParentCategoryId = down2.CategoryId
- WHERE root.ParentCategoryId = 0
- ORDER
- BY root_name
- , down1_name
- , down2_name
- , down3_name
Hope you like it. Thank you for reading. Like and share, and keep learning.

Asal RajabiPosted Feb 1, 2021, 4:40 PM
This is 3Level ,not Supported N Level
Uma KumarPosted Dec 21, 2019, 4:43 AM
Hi, buddy .. how i show this menu on all page.. mean when i change the page from HomeController/Index to other controller or cshtml it get disapper...
ulas yamanPosted May 6, 2019, 9:41 AM
I got an error : " Record Not Found!!"
onais ahmerPosted Jun 28, 2018, 11:48 PM
You can do in a complex style can give me any link to populate tree view .. I have seen this article ""https://www.codeproject.com/Articles/1077799/Creating-Dynamics-Tree-View-Menu-in-ASP-NET-MVC-in "" The issue is when i disable the click to the child node it can disable all node disable i think in your solution child node treat seprately but i cant understand your project through its complexicty ..
Mark GregoryPosted Jun 12, 2018, 2:04 AM
Awesome guide, thanks for posting!
Muhammad BaiquniPosted May 24, 2018, 12:58 AM
If I want the TreeView data From SQL Query to be menu, how can I archive?
Akshaya arumugamPosted Mar 7, 2018, 12:55 AM
<a href=\"/Product/ListProduct?cat=" + down2.CategoryId + "\">" + down2.CategoryName + "</a>; this line in home controller specifies what?
Pintu AliPosted Dec 23, 2017, 3:39 AM
Bakwas hai ye code
Xolani GumedePosted Jun 22, 2017, 6:30 AM
I have downloaded the project and ran it however only the Parent tabs are only showing and when i click on the tabs i get a 404.
Satyaprakash SamantarayPosted May 10, 2017, 12:16 AM
Nice one , i like it
Hiten PandyaPosted May 10, 2017, 12:10 AM
Good one bro..........