MVC Sitemap renders empty when the current action is not in the Mvc.sitemap file

1.5k views Asked by At

Is it possible to force the sitemap control to render the menu when the current action is not listed in the MVC.sitemap file?

I have a simple top nav. When the current action is in the sitemap, the call to .Menu() will render the correct <ul><li>.. data. However, if I got to a page that is not in the sitemap such as /Home/Login, then it will not render any html at all (not even a comment, just empty space). This isn't an [authorize] issue; the menu is fine when i'm in '/Home/Index'.

It seems like it should render what was requested, but just not set the IsCurrentNode and IsNodeInPath properties. Here is the call I am making

<div id="main-nav">
    @Html.MvcSiteMap().Menu(0, true, true, 1)
</div>

The Mvc.sitemap file:

<mvcSiteMapNode title="Home" controller="Home" action="Index">
    <mvcSiteMapNode title="Form New Human" controller="Person" action="Create"/>
    <!-- there is no mvcSiteMapNode for "Home" "Login" -->
</mvcSiteMapNode>
1

There are 1 answers

0
Andrew On BEST ANSWER

Found the way around it. It apparently isn't a built in extension method, or at least I couldn't find one. You could call Html.MvcSitemap().Menu(Html.MvcSiteMap.Provider.RootNode,...) but I didn't want to instantiate the helper twice.

<div id="main-nav">
@{
    var sm = Html.MvcSiteMap();
    @sm.Menu(sm.Provider.RootNode, true, true, 2);  // 2 levels (home, plus main nav)
}
</div>

Looking around in the disassembly seems to show that it works a little like this:

  • You really need a starting node
  • If you don't give it one, it tries to find one based on the current node
    • plus restrictions (forward searching, depth restrictions, etc)
    • if you want nodes from level 1, you have to know what level you are on
  • Since that returns null, starting node is null, which means the helper writes an empty string

There may be a combination of tricks, or an overload or two, which can be finagled into doing this, but I can't find it right now. This works for my needs (simple top menu). There has to be a simpler way to do this, something with wild cards, or route based, with a closest match thing going on. I figured menus were a fairly standard part of a web app, and this would be covered :)