ASP.NET Core MVC 中如何运行旧版ASP.NET MVC的递归菜单@helper代码
解决方案
核心原因
ASP.NET Core MVC 已不再支持原有ASP.NET MVC中的@helper声明语法,这是你原有代码无法运行的根本原因。你可以通过以下两种常用方案实现同等的递归菜单效果:
方案1:使用递归局部视图(推荐,结构清晰易维护)
这种方案不需要修改原有逻辑结构,只需拆分出两个局部视图即可:
- 新建
Views/Shared/_MenuPartial.cshtml局部视图,用于渲染根级菜单:
@model IEnumerable<Menuler> @foreach (var rootcat in Model.OrderBy(x => x.Sira)) { <li> <a href="@rootcat.Url">@rootcat.MenuAdi</a> @if (rootcat.AltMenuler.Any()) { <ul class="dropdown-menu"> <partial name="_SubMenuPartial" model="@rootcat" /> </ul> } </li> }
- 新建
Views/Shared/_SubMenuPartial.cshtml局部视图,用于递归渲染子菜单:
@model Menuler @foreach (var altmenu in Model.AltMenuler.OrderBy(x => x.Sira)) { <li> <a href="@altmenu.Url">@altmenu.MenuAdi</a> @if (altmenu.AltMenuler.Any()) { <ul> <partial name="_SubMenuPartial" model="@altmenu" /> </ul> } </li> }
- 在需要展示菜单的主视图中调用即可:
<ul> <partial name="_MenuPartial" model="@anamenu" /> </ul>
方案2:使用@functions定义内嵌辅助方法(贴合原有写法,无需新增视图文件)
直接在需要用到菜单的视图顶部添加如下代码即可:
@using Microsoft.AspNetCore.Html @using Microsoft.AspNetCore.Mvc.Rendering @functions { private IHtmlContent CreateMenu(IEnumerable<Menuler> anamenu) { var contentBuilder = new HtmlContentBuilder(); foreach (var rootcat in anamenu.OrderBy(x => x.Sira)) { var liTag = new TagBuilder("li"); var aTag = new TagBuilder("a"); aTag.Attributes.Add("href", rootcat.Url); aTag.InnerHtml.Append(rootcat.MenuAdi); liTag.InnerHtml.AppendHtml(aTag); if (rootcat.AltMenuler.Any()) { var ulTag = new TagBuilder("ul"); ulTag.AddCssClass("dropdown-menu"); ulTag.InnerHtml.AppendHtml(CreateSubMenuItems(rootcat)); liTag.InnerHtml.AppendHtml(ulTag); } contentBuilder.AppendHtml(liTag); } return contentBuilder; } private IHtmlContent CreateSubMenuItems(Menuler menu) { var contentBuilder = new HtmlContentBuilder(); foreach (var altmenu in menu.AltMenuler.OrderBy(x => x.Sira)) { var liTag = new TagBuilder("li"); var aTag = new TagBuilder("a"); aTag.Attributes.Add("href", altmenu.Url); aTag.InnerHtml.Append(altmenu.MenuAdi); liTag.InnerHtml.AppendHtml(aTag); if (altmenu.AltMenuler.Any()) { var ulTag = new TagBuilder("ul"); ulTag.InnerHtml.AppendHtml(CreateSubMenuItems(altmenu)); liTag.InnerHtml.AppendHtml(ulTag); } contentBuilder.AppendHtml(liTag); } return contentBuilder; } }
在视图需要输出菜单的位置直接调用方法:
<ul> @CreateMenu(anamenu) </ul>
注意事项
- 请确保你的视图已经引用了
Menuler类所在的命名空间,你可以在当前视图顶部添加@using 你的项目命名空间.Models,或者直接在Views/_ViewImports.cshtml中全局添加该命名空间,避免每个视图重复引用。 - 原有代码中的
Count() > 0替换为Any()可以提升性能,无需遍历整个集合即可判断是否存在元素。
内容的提问来源于stack exchange,提问作者eyyup
相关产品推荐
相关产品推荐

