2014-02-21 36 views
3

我有這樣的網站地圖:MVCSiteMapProvider麪包屑不正確的父節點ID

<mvcSiteMapNode title="Projects" controller="Projects" action="Index" key="Home" visibility="!*"> 
<mvcSiteMapNode title="Projects" controller="Projects" action="Index"> 
    <mvcSiteMapNode title="Project" controller="Projects" action="Details" preservedRouteParameters="id"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" preservedRouteParameters="id"> 
     <mvcSiteMapNode title="Edit Session" controller="Sessions" action="Edit" preservedRouteParameters="id"/> 
    </mvcSiteMapNode> 
    </mvcSiteMapNode> 
</mvcSiteMapNode> 
<mvcSiteMapNode title="My Account" controller="Account" action="ChangePassword" /> 
<mvcSiteMapNode title="Admin" controller="Admin" action="Index" > 
    <mvcSiteMapNode title="Create User" controller="Admin" action="AddUser" /> 
    <mvcSiteMapNode title="Manage Users" controller="Admin" action="Users" /> 
</mvcSiteMapNode> 

當我去會議詳細信息頁面,在麪包屑顯示:

Projects > Project > Session 

但是該項目的鏈接,這進入「項目詳細信息」頁面,使用與會話相同的ID,而不是來自該項目的項目。

我嘗試將inheritedRouteParameters="id"添加到「會話詳細信息」頁面,但它沒有改變任何內容。

編輯: 我添加不同preservedRouteParameters,但現在「項目」鏈接回/項目/細節沒有ID連接。

回答

3

如果關鍵字名稱匹配,preserveRouteParameters將始終複製當前請求中的值,但不會假定「id」是什麼。因此,如果您在同時顯示的2個節點的preservedRouteParameters中使用「id」,則需要確保它們具有相同的含義。

解決此問題的一種方法是對每種情況使用不同的鍵名(例如,「projectId」和「sessionId」)。然後,您可以在子節點上保留它們,以便「記住」它屬於的父項。

<mvcSiteMapNode title="Project" controller="Projects" action="Details" preservedRouteParameters="projectId"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" preservedRouteParameters="projectId,sessionId"> 

您可能需要修改你的路由讓本作是可以接受你的要求的網址,但這個工作父ID必須是該路線的一部分(通常是URL)子節點。這是一個與上述節點配置相匹配的示例。

public class RouteConfig 
{ 
    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.MapRoute(
      name: "SessionRoute", 
      url: "Project/{projectId}/{sessionId}", 
      defaults: new { controller = "Sessions", action = "Details" }); 

     routes.MapRoute(
      name: "ProjectRoute", 
      url: "Project/{projectId}", 
      defaults: new { controller = "Projects", action = "Details" }); 

     routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ); 
    } 
} 

看一看在MvcSiteMapProvider-強制-A-匹配-2級別項目in this demo,看看究竟如何可以做到這一點。請注意,添加路由是可選的 - 如果您不介意URL中的查詢字符串參數,則始終可以使用默認路由。

如果這不適合你,那麼你可以結合使用一個節點參數的preservedRouteParmeters和顯式設置另一個參數。

<mvcSiteMapNode title="Project" controller="Projects" action="Details" preservedRouteParameters="projectId"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" id="1" preservedRouteParameters="projectId"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" id="2" preservedRouteParameters="projectId"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" id="3" preservedRouteParameters="projectId"> 

或者您可以爲每個「ID」組合創建一個節點。

<mvcSiteMapNode title="Project" controller="Projects" action="Details" id="1"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" id="1"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" id="2"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" id="3"> 
</mvcSiteMapNode> 
<mvcSiteMapNode title="Project" controller="Projects" action="Details" id="2"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" id="4"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" id="5"> 
    <mvcSiteMapNode title="Session" controller="Sessions" action="Details" id="6"> 
</mvcSiteMapNode> 

對於這些過去的2種選擇,通常最好使用DynamicNodeProvider來填充動態數據,而不是XML標記他們都放棄了。

這些方法創建更乾淨的URL,但也使用更多的RAM。一般來說,對於管理頁面,最好使用稍微草率的URL(preservedRouteParmaters)並使用動態節點(和RAM)保存需要搜索引擎索引的頁面。

inheritedRouteParameters僅用於在XML配置中從父節點繼承值,並且在請求級別無效。

順便說一句 - 您必須確保您在每個節點上具有唯一的路由值組合。在你的例子中,前2個節點具有完全相同的路由值,這意味着第二個節點將永遠不會匹配,因爲第一個匹配總是獲勝。

+0

是否因爲我使用默認路由和不同的控制器而導致我無法正常運行preservedRouteParameters解決方案? – Shawn

+0

它確實與路由無關 - 這是因爲您在同一時間可能會顯示的2個不同節點中使用的參數名稱相同。 preservedRouteParameters不會記住跨請求的id,它只會從當前請求中複製它。如果您有一個祖先節點使用相同的ID用於不同的目的,它將在查看子節點時使用錯誤的ID。 – NightOwl888

+0

看看這篇文章,以更好地瞭解如何保護路由參數的作品。 http://www.shiningtreasures.com/post/2013/09/02/how-to-make-mvcsitemapprovider-remember-a-user-position – NightOwl888