在MVC中使用递归分部视图会引发Stack空InvalidOperationException
本文关键字:Stack InvalidOperationException 视图 MVC 递归 | 更新日期: 2023-09-27 18:09:01
我想用递归元素创建一个递归菜单。我的第一种方法是为了重用代码而使用部分视图。唉,当我运行代码时,它抛出了一个"System"。InvalidOperationException" "Stack empty"错误。
我正在用AutoMapper映射来自web服务的数据,这会产生以下实体:
public interface INavigationItemContract
{
int Id { get; set; }
string Title { get; set; }
int ParentId { get; set; }
string Url { get; set; }
bool DisplayInMenu { get; set; }
decimal SortOrder { get; set; }
IEnumerable<IPageBaseContract> Pages { get; set; }
IEnumerable<INavigationItemContract> Sites { get; set; }
}
初始化菜单的部分视图(_Menu.cshtml):
@model IEnumerable<INavigationItemContract>
<div class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
@foreach (var navigationItem in Model)
{
@Html.Partial("_MenuItem", navigationItem);
}
</ul>
</div>
</div>
显示菜单项的部分(_MenuItem.cshtml):
@model INavigationItemContract
@if (Model.Pages != null && Model.Pages.Any())
{
if (Model.Pages.Count() == 1 || !Model.DisplayInMenu)
{
// Only one page, so this will be the default.
// Other option is that the pages should not be displayed, so then we'll only display the link to the site.
<li><a href="@Model.Url">@Model.Title</a></li>
}
else
{
<li>
<a href="#">@Model.Title</a>
<ul class="dropdown-menu">
@foreach (var page in Model.Pages)
{
<li><a href="@page.RelativeUrl">@page.Title</a></li>
}
@foreach (var site in Model.Sites)
{
@Html.Partial("_MenuItem", site)
}
</ul>
</li>
}
}
替换
时@Html.Partial("_MenuItem", site)
<li>@site.Title</li>
一切都像一个魅力(除了事实,它不是理想的结果)。
我也尝试了以下方法:
- 创建DisplayTemplate
- 使用Html。用RenderPartial代替Html。部分
异常出现在_MenuItem.cshtml:
@Html.Partial("_MenuItem", site)
它不会在第一次调用部分时发生(在_Menu.cshtml中),只会在_MenuItem中发生。CSHTML本身,当它调用自己时。
为什么我得到这个异常?那么解决方案是什么呢?
我找到了一个解决方法。这个异常仍然让我感到困惑,但是我可以继续呈现菜单(尽管我没有能力在helper代码上设置断点).
@ model IEnumerable
@helper RecursiveMenuItem(INavigationItemContract menuItem)
{
if (menuItem.Pages != null && menuItem.Pages.Any())
{
if (menuItem.Pages.Count() == 1 || !menuItem.DisplayInMenu)
{
// Only one page, so this will be the default.
// Other option is that the pages should not be displayed, so then we'll only display the link to the site.
<li><a href="@menuItem.Url">@menuItem.Title</a></li>
}
else
{
<li>
<a href="#">@menuItem.Title</a>
<ul class="dropdown-menu">
@foreach (var page in menuItem.Pages)
{
<li><a href="@page.Url">@page.Title</a></li>
}
@foreach (var site in menuItem.Sites)
{
@RecursiveMenuItem(site)
}
</ul>
</li>
}
}
}
<div role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="">Home</a></li>
@foreach (var menuItem in Model)
{
@RecursiveMenuItem(menuItem)
}
</ul>
</div>
</div>
不确定,但是您不应该通过替换:
来显式地在模型中使用枚举吗?@foreach (var navigationItem in Model)
@foreach (var navigationItem in Model.Sites)