I am just trying to display nth relation using ul
and li
in razor using recursive function call. Suppose I have db table where I store parent child
Your code is not able to find a function ShowTree taking a parameter of type ICollection<MenuItem>
when it executes the line
@ShowTree(item.Children)
because item.Children is of type ICollection<MenuItem>
. The function ShowTree in your code takes a parameter of a different type, List<MenuDTO>
, which is not the same as ICollection<MenuItem>
. As a result, the runtime reports the CS1502 error you see.
After realizing that you were looking for a recursive solution, I have modified the code to do just that.
Action Code
public ActionResult Index()
{
List<MenuItem> allMenu = new List<MenuItem>
{
new MenuItem {Id=1,Name="Parent 1", ParentId=0},
new MenuItem {Id=2,Name="child 1", ParentId=1},
new MenuItem {Id=3,Name="child 2", ParentId=1},
new MenuItem {Id=4,Name="child 3", ParentId=1},
new MenuItem {Id=5,Name="Parent 2", ParentId=0},
new MenuItem {Id=6,Name="child 4", ParentId=4}
};
List<MenuItem> mi = allMenu
.Where(e => e.ParentId == 0) /* grab only the root parent nodes */
.Select(e => new MenuItem
{
Id = e.Id,
Name = e.Name,
ParentId = e.ParentId,
Children = GetChildren(allMenu, e.Id) /* Recursively grab the children */
}).ToList();
ViewBag.menusList = mi;
return View();
}
/// <summary>
/// Recursively grabs the children from the list of items for the provided parentId
/// </summary>
/// <param name="items">List of all items</param>
/// <param name="parentId">Id of parent item</param>
/// <returns>List of children of parentId</returns>
private static List<MenuItem> GetChildren(List<MenuItem> items, int parentId)
{
return items
.Where(x => x.ParentId == parentId)
.Select(e => new MenuItem
{
Id = e.Id,
Name = e.Name,
ParentId = e.ParentId,
Children = GetChildren(items, e.Id)
}).ToList();
}
Razor Code
@{
var menuList = ViewBag.menusList as List<Scaffolding.Controllers.MenuItem>;
@ShowTree(menuList);
}
@helper ShowTree(List<Scaffolding.Controllers.MenuItem> menusList)
{
if (menusList != null)
{
foreach (var item in menusList)
{
<li>
<span>@item.Name</span>
@if (item.Children.Any())
{
<ul>
@ShowTree(item.Children)
</ul>
}
</li>
}
}
}
I fixed and did the job this way
the problem was in logic of razor code and also i comment this line //.Where(e => e.ParentId == 0)
here i am adding working code.
working code sample
@helper ShowTree(List<NestedChild.Controllers.MenuItem> menu, int? parentid = 0, int level = 0)
{
var items = menu.Where(m => m.ParentId == parentid);
if (items.Any())
{
if (items.First().ParentId > 0)
{
level++;
}
<ul>
@foreach (var item in items)
{
<li>
@item.Name
</li>
@ShowTree(menu, item.Id, level);
}
</ul>
}
}
@{
var menuList = ViewBag.menusList as List<NestedChild.Controllers.MenuItem>;
@ShowTree(menuList);
}
public ActionResult Index()
{
List<MenuItem> allMenu = new List<MenuItem>
{
new MenuItem {Id=1,Name="Parent 1", ParentId=0},
new MenuItem {Id=2,Name="child 1", ParentId=1},
new MenuItem {Id=3,Name="child 2", ParentId=1},
new MenuItem {Id=4,Name="child 3", ParentId=1},
new MenuItem {Id=5,Name="Parent 2", ParentId=0},
new MenuItem {Id=6,Name="child 4", ParentId=4}
};
List<MenuItem> mi = allMenu
//.Where(e => e.ParentId == 0) /* grab only the root parent nodes */
.Select(e => new MenuItem
{
Id = e.Id,
Name = e.Name,
ParentId = e.ParentId,
//Children = allMenu.Where(x => x.ParentId == e.Id).ToList()
}).ToList();
ViewBag.menusList = mi;
return View();
}