private bool NodeMatchesRoute not correct in v3

Mar 20, 2011 at 10:08 AM


When trying to debug, i found that the method  private bool NodeMatchesRoute(MvcSiteMapNode mvcNode, IDictionary<string, object> values) works incorrectly.


 - values contains: {<action,Action>,<controller,Home>,<id,UrlParameter.Optional>,<area,Admin>}

- mvcNode contains: {<action,Action>,<controller,Home>,<id,UrlParameter.Optional>,<area,"">}

this method will return true.

And then, in private SiteMapNode FindSiteMapNode(HttpContext context, RouteData routeData) at section:

if (NodeMatchesRoute(RootNode as MvcSiteMapNode, routeData.Values))
        node = RootNode;

(so when I access to Area with {Controller/Action/Id} same as area's, the area node always  refer to RootNode)

Does the NodeMatchesRoute() works as you want? If yes, can you add more parameters in sitemap file to ignore this case (I don't want to use RootNode when I access to area)

Mar 25, 2011 at 10:13 PM

NodeMatchesRoute checks all route values, so area should be checked as well? Can you doble check this?

BTW Feel free to contribute a corrected version :-)

Mar 26, 2011 at 1:07 AM

I've look in deepth for this function, and i thing it's very hard to do a correct check. I've inject some code to make sure this function is correct for me, but not sure for all case. You can see as:

(in NodeMatchesRoute(MvcSiteMapNode mvcNode, IDictionary<string, object> values))

foreach (var pair in values)
                        //HACK 1: Check for same values
                        if (!CompareMustMatchRouteValues(mvcNode.RouteValues, values))
                            return false;


and function: CompareMustMatchRouteValues()

 private static bool CompareMustMatchRouteValues(IDictionary<string, object> mvcNodeRouteValues, IDictionary<string, object> routeValues)
            var routeKeys = mvcNodeRouteValues.Keys;

            foreach (var pair in routeValues)
                if (routeKeys.Contains(pair.Key) &&
                    mvcNodeRouteValues[pair.Key].ToString().ToLowerInvariant() != pair.Value.ToString().ToLowerInvariant())
                    return false;
            return true;


I thing we should return a list of candidate node that matching current route, and then from this list, choose the best choice :)