ASP.NET MVC StackOverflowException Loading dynamic menu from xml in Layout

一个人想着一个人 提交于 2019-12-23 05:12:22

问题


I try to put a dynamic menu (load from xml) in my Layout but I've got a StackOverflowException in PartialController.cs/MainMenu()

I don't understand why my code throw a StackOverflowException because I don't have a loop (or I don't see it !).

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>
}

PartialController.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);
}

navigation.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>

EDIT : This is the detail of the exception (there's no StackTrace):

System.StackOverflowException was unhandled An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll

{Cannot evaluate expression because the current thread is in a stack overflow state.}

In the Call Stack, I see the line "Html.RenderAction("MainMenu", "Partial");" constantly called but I don't know why.


回答1:


There is an infinite loop here. The problem is that you do this in your Layout:

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

And then in your Action you do this:

return View(menu);

When you call return View() your view is rendered, including your layout. So your layout then renders your @Html.RenderAction(...) again... which calls your View()... which renders your Layout... etc.. etc.. etc..

You solve this by returning a PartialView() which does not render your Layout, or by rendering a view with Layout set to Null. This is the primary difference between a View() and a PartialView(), Layout rendering.



来源:https://stackoverflow.com/questions/27298137/asp-net-mvc-stackoverflowexception-loading-dynamic-menu-from-xml-in-layout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!