problem with currentnode

Apr 8, 2011 at 3:46 PM

I have the following sitemap:

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" enableLocalization="true">
  <mvcSiteMapNode title="$resources:Global,Menu_General" clickable="false">
    <mvcSiteMapNode title="$resources:Global,Menu_General_Information" area="General" controller="Information" action="Index" />
    <mvcSiteMapNode title="$resources:Global,Menu_General_JobOffers" area="General" controller="JobOffers" action="Index" />
    <mvcSiteMapNode title="$resources:Global,Menu_General_Contact" area="General" controller="Contact" action="Index" />
    <mvcSiteMapNode title="$resources:Global,Menu_ItConsultancy" clickable="false" />
    <mvcSiteMapNode title="$resources:Global,Menu_ItConsultancy_Activities" area="ItConsultancy" controller="Activities" action="Index" />
    <mvcSiteMapNode title="$resources:Global,Menu_ItConsultancy_References" area="ItConsultancy" controller="References" action="Index" />
    <mvcSiteMapNode title="$resources:Global,Menu_AdminConsultancy" clickable="false" />
    <mvcSiteMapNode title="$resources:Global,Menu_AdminConsultancy_Activities" area="ItConsultancy" controller="Activities" action="Index" />
  </mvcSiteMapNode>
</mvcSiteMap>

If i check @SiteMap.CurrentNode.Title it always returns me the top row. What am i doing wrong?

I have implemented a custom template for my navigation but it is hard for me to believe that could be the problem.

My navigation is loaded in my master page (_Layout.cshtml), could that be the problem?

I am using ASP.Net mvc 3 with the razor engine with version 3 of the provider.

Apr 13, 2011 at 8:28 AM

Same issue...

the problem should be the "inheritance" from the underling "simple" SitemapProvider

it doesn't consider "Areas", that is, nodes with same controller name and action name BUT different Area are equal!!!!

so it happens that the first node matching controller name and action name wins..!

 

in the code:

file: SiteMapNodeModelMapper.cs, line 34

IsCurrentNode = node == node.Provider.CurrentNode, 

this is wrong!!!! it doesn't consider the "area"

 

 

file: SiteMapPathHelper.cs, line 44

var model = BuildModel(helper, helper.Provider.CurrentNode);

helper.Provider.CurrentNode!!!! and the Area??

this is wrong!!!! it doesn't consider the "area"

 

FIXING:

 

fix a) don't use same control name even in different areas!!

fix b) write an extender:

 public static class SiteMapNodeModelExtender
 {

  public static bool IsRealCurrentNode(this MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel node, RouteData routeData)
  {
   var node_Area = node.Area.ToString();

   var currentArea = (routeData.DataTokens["area"] == null) ? "" : routeData.DataTokens["area"].ToString();

   bool ret=
    ((node.Action.ToString() == routeData.Values["action"].ToString())
     && (node.Controller.ToString() == routeData.Values["controller"].ToString())
      && (node_Area == currentArea));   
   
   return ret; 
  
  }
 }

 ...etc etc...

 

fix c) modify the MvcSiteMapProvider ....

  Hope this helps

 

 

 

 

 

 

 

 

 

 

 

 

Coordinator
Apr 20, 2011 at 3:12 PM

Should be fixed now (3.1.0 branch)

Feb 2, 2012 at 2:11 PM

Or

    public static bool IsRealCurrentNode(this MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel node)
    {
      var httpContext = new HttpContextWrapper(HttpContext.Current);
      var routeData = RouteTable.Routes.GetRouteData(httpContext);
      if ( routeData != null )
      {
        var controllerName = routeData.GetRequiredString("controller");
        var actionName = routeData.GetRequiredString("action");
        var areaName = routeData.DataTokens["area"] as string;

        actionName = actionName ?? "Index"; // default action
        controllerName = controllerName ?? "Home"; // Default controller
        areaName = areaName ?? "";

        return string.Equals(node.Controller, controllerName, StringComparison.InvariantCultureIgnoreCase)
            && string.Equals(node.Action, actionName, StringComparison.InvariantCultureIgnoreCase)
             && string.Equals(node.Area, areaName, StringComparison.InvariantCultureIgnoreCase);
      }
      return false;
    }

by dgavarin