ASP.NET MVC StackOverflowException 从布局中的 xml 加载动态菜单

本文关键字:xml 加载 动态 菜单 布局 NET MVC StackOverflowException ASP | 更新日期: 2023-09-27 18:33:04

我尝试在我的布局中放置一个动态菜单(从xml加载),但我在PartialController中有一个StackOverflowException.cs/MainMenu()

我不明白为什么我的代码会抛出 StackOverflowException,因为我没有循环(或者我没有看到它!

Layout.cshtml :

....
<div id="menu">
    @if (Request.IsAuthenticated)
    {
        Html.RenderAction("MainMenu", "Partial");
    }
</div>
....

MainMenu.cshtml :

@model Geosys.BoT.Portal.POC.Business.Menu
@foreach (var item in Model.Nodes)
{
    <ul>
        <li>
            @item.Name
            <ul>
                @foreach (var subItem in item.Links)
                {
                    <li>
                        @Html.ActionLink(subItem.Name, subItem.Action, subItem.Controller)
                    </li>
                }
            </ul>
        </li>
    </ul>
}

部分控制器.cs :

[ChildActionOnly]
public ActionResult MainMenu()
{
    var menu = new Menu { Nodes = new List<NodeMenu>() };
    var xmlData = System.Web.HttpContext.Current.Server.MapPath("~/Content/navigation.xml");
    if (xmlData == null)
    {
        throw new ArgumentNullException("xmlData");
    }
    var xmldoc = new XmlDataDocument();
    var fs = new FileStream(xmlData, FileMode.Open, FileAccess.Read);
    xmldoc.Load(fs);
    var xmlnode = xmldoc.GetElementsByTagName("node");
    for (var i = 0; i <= xmlnode.Count - 1; i++)
    {
        var xmlAttributeCollection = xmlnode[i].Attributes;
        if (xmlAttributeCollection != null)
        {
            var nodeMenu = new NodeMenu { Name = xmlAttributeCollection["title"].Value, Links = new List<LinkMenu>() };
            if (xmlnode[i].ChildNodes.Count != 0)
            {
                for (var j = 0; j < xmlnode[i].ChildNodes.Count; j++)
                {
                    var linkMenu = new LinkMenu();
                    var xmlNode = xmlnode[i].ChildNodes.Item(j);
                    if (xmlNode != null)
                    {
                        if (xmlNode.Attributes != null)
                        {
                            linkMenu.Name = xmlNode.Attributes["title"].Value;
                            linkMenu.Action = xmlNode.Attributes["action"].Value;
                            linkMenu.Controller = xmlNode.Attributes["controller"].Value;
                            linkMenu.Key = xmlNode.Attributes["key"].Value;
                            nodeMenu.Links.Add(linkMenu);
                        }
                    }
                }
            }
            menu.Nodes.Add(nodeMenu);
        }
    }
    return View(menu);
}

导航.xml:

<nodes>
  <node title="User Management">
    <link title="Create User" action="CreateUser" controller="UserManagement" key="UM_CREATEUSER" />
    <link title="Users List" action="UsersList" controller="UserManagement" key="UM_USERSLIST" />
    <link title="Import Users" action="ImportUsers" controller="UserManagement" key="UM_IMPORTUSERS" />
  </node>
</nodes>

编辑:这是异常的详细信息(没有 StackTrace):

System.StackOverflowException 是未处理的 mscorlib 中发生了类型为"System.StackOverflowException"的未处理异常.dll

{无法计算表达式,因为当前线程处于堆栈溢出状态。

在调用堆栈中,我看到"Html.RenderAction("MainMenu","Partial");"行不断调用,但我不知道为什么。

ASP.NET MVC StackOverflowException 从布局中的 xml 加载动态菜单

这里有一个无限循环。 问题是你在布局中这样做:

@Html.RenderAction("MainMenu", "Partial");

然后在您的操作中执行此操作:

return View(menu);

调用return View()时,将呈现视图,包括布局。 因此,您的布局会再次渲染您的@Html.RenderAction(...)...调用您的视图()...这会渲染您的布局...等。。等。。等。。

您可以通过返回不呈现布局的PartialView()或通过呈现布局设置为 Null 的视图来解决此问题。 这是View()PartialView()、布局渲染的主要区别。