2014-12-04 74 views
0

從XML加載動態菜單我試圖把一個動態菜單(從XML負載)在我的佈局,但我在PartialController.cs/MainMenu的()ASP.NET MVC StackOverflowException在佈局

我有一個StackOverflowException不明白爲什麼我的代碼拋出一個StackOverflowException,因爲我沒有一個循環(或者我沒有看到它!)。

Layout.cshtml:

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

MainMenu.cshtml:

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> 

編輯: 這是異常的細節(有沒有堆棧跟蹤):

System.StackOverflowException了未處理 類型的未處理的異常 'System.StackOverflowException' 出現在mscorlib.dll

{因爲當前線程堆棧溢出狀態無法計算表達式。}

調用堆棧,我看行「Html.RenderAction( 「MainMenu」,「部分」);「不斷地打電話,但我不知道爲什麼。

+2

你是什麼意思,我在這段代碼中看到3個循環。 1'foreach'循環和2'for'循環。如果您可以從溢出異常中添加堆棧跟蹤,這可能有助於縮小堆棧溢出的位置。 – danludwig 2014-12-04 15:49:47

+0

您可以嘗試使用LINQ表達式來獲取選定節點而不是循環的列表(如果需要幫助,請告訴我)。附註:最後在'stackoverflow.com'上看到了'stackoverflow exception' :)。 – 2014-12-04 15:54:19

+0

當我說「我沒有看到一個循環」時,我的意思是我沒有看到遞歸循環。我知道我有3個循環,但stackoverflow異常不在這些循環中。多次調用MainMenu()方法。我會把堆棧跟蹤放在main中。 – 2014-12-05 08:24:19

回答

2

這裏有一個無限循環。問題是,你在你的佈局做到這一點:

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

然後在你的行動,你這樣做:

return View(menu); 

當你調用return View()您的視圖顯示,包括您的佈局。因此,您的佈局然後再次呈現您的@Html.RenderAction(...) ...哪些調用您的視圖()...哪些呈現您的佈局...等等..等..

您解決此問題通過返回PartialView()哪渲染您的佈局,或者通過渲染布局設置爲Null的視圖。這是View()PartialView()佈局渲染之間的主要區別。

+0

我在其他地方發現了這個解決方案,但你是唯一解釋原因的解決方案。謝謝! – leahcimp 2015-04-02 00:27:54