Moving from 2.3* to 3* with MVC3/Razor

Feb 4, 2011 at 4:11 PM

It seems like it takes me many, many iterations of changing options before I can find the configuration that works for me.  The new version has different parameter sets so here is what am I trying to re-create in the new version.

 

Html.MvcSiteMap().Menu("MvcSiteMapProvider", false, 1, false, "active", "active-trail", 0, new { @class = "nice-menu nice-menu-down" }, 1)

Html.MvcSiteMap().Submenu("MvcSiteMapProvider", "active", 1, 0, new{@class="menu"})

 

So the first one was pretty straightforward and I replaced it with the following.  I'm not quite sure why I can't leave MvcSiteMap's constructor blank and as have the specified default sitemapprovider in my web.config (installed with NuGet)

 

Html.MvcSiteMap("MvcSiteMapProvider").Menu(1, 1)

 

The second one I haven't had much luck with.  The best I have come up with so far follows. The problem with this one is when using my tree structure, also shown below, if Test 2 is active I do not see the submenu of child 3, childchild4, childchild5, child7 like I would expect. I only see that submenu when one of those children are active.  Two other things I have noticed. First, when I set the second parameter to false I still see both parent nodes when childchild4 is active.  The second is that specifying a resourceKey on sitemapnode Home causes the title to not be shown.

 

Html.MvcSiteMap("MvcSiteMapProvider").Menu(2, true, false, 99, false, false);
<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" enableLocalization="true">
  <mvcSiteMapNode title="Regress" clickable="false" changeFrequency="Always" updatePriority="Normal" key="Home">
    <mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal" />
    <mvcSiteMapNode title="Test 1" controller="Home" action="Test1" changeFrequency="Always" updatePriority="Normal" />
    <mvcSiteMapNode title="Test 2" controller="Home" action="Test2" changeFrequency="Always" updatePriority="Normal">
      <mvcSiteMapNode title="child 3" controller="Home" action="Test3" changeFrequency="Always" updatePriority="Normal">
        <mvcSiteMapNode title="childchild 4" controller="Home" action="Test4" changeFrequency="Always" updatePriority="Normal" />
        <mvcSiteMapNode title="childchild 5" controller="Home" action="Test5" changeFrequency="Always" updatePriority="Normal" />
      </mvcSiteMapNode>
      <mvcSiteMapNode title="child 7" controller="Home" action="Test7" changeFrequency="Always" updatePriority="Normal" />
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Test 8" controller="Home" action="Test8" changeFrequency="Always" updatePriority="Normal">
      <mvcSiteMapNode title="child 6" controller="Home" action="Test6" changeFrequency="Always" updatePriority="Normal" />
      <mvcSiteMapNode title="child 9" controller="Home" action="Test9" changeFrequency="Always" updatePriority="Normal" />
    </mvcSiteMapNode>
  </mvcSiteMapNode>
</mvcSiteMap>

 

 

false
Feb 8, 2011 at 2:24 PM
Edited Feb 8, 2011 at 2:26 PM

Urugh, Just noticed this post and wish I would have read it before I started trying to use the MVC SiteMap provider.

 

I've got the same issues with you on the Children. In my Mvc.Sitemap I have

 

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" enableLocalization="false">
  <mvcSiteMapNode title="Home" controller="Home" action="Index">
    <mvcSiteMapNode title="ChildOne" controller="Home" action="Index"/>
    <mvcSiteMapNode title="ChildTwo" controller="Home" action="Index"/>
    <mvcSiteMapNode title="ChildThree" controller="Home" action="Index"/>
  </mvcSiteMapNode>
</mvcSiteMap>

 

Yet calling this code (similar to the default templates):

 

    <ul class="container_12" id="main-menu">
        @foreach (var node in Model.Nodes) { 
            <li class="home current">@Html.DisplayFor(m => node) 
                @node.Children.Count
           </li>
        }
    </ul>

Should print all of the parent nodes and the number of children.

What it actually does is print out the parent node (I only have one in the example) and "0" as the number of children.
I basically cannot get to the children at all.
What is going on????

 

Feb 8, 2011 at 3:18 PM

I can print children.  Whats your .Menu() call and sitmeap file look like.

Feb 8, 2011 at 3:25 PM

I've worked out that the call to print the sitemap is just printing the first node's children:

Sitemap:

 

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" enableLocalization="true">
  <mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
    <mvcSiteMapNode title="Dashboard" controller="Home" action="Index"/>
    <mvcSiteMapNode title="My Profile" controller="Home" action="Index"/>
    <mvcSiteMapNode title="My Jobs" controller="Home" action="Index"/>
  </mvcSiteMapNode>
  <mvcSiteMapNode title="Workplace" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
    <mvcSiteMapNode title="Jobs" controller="Home" action="Index"/>
    <mvcSiteMapNode title="Calendar" controller="Home" action="Index"/>
    <mvcSiteMapNode title="Customers" controller="Home" action="Index"/>
    <mvcSiteMapNode title="Equipment" controller="Home" action="Index"/>
  </mvcSiteMapNode>
  <mvcSiteMapNode title="Reports" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
    <mvcSiteMapNode title="Reports" controller="Home" action="Index"/>
    <mvcSiteMapNode title="Search" controller="Home" action="Index"/>
  </mvcSiteMapNode>
  <mvcSiteMapNode title="Settings" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
    <mvcSiteMapNode title="Control Panel" controller="Home" action="Index"/>
  </mvcSiteMapNode>
  <mvcSiteMapNode title="Support" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
    <mvcSiteMapNode title="Help" controller="Home" action="Index"/>
    <mvcSiteMapNode title="Feedback" controller="Home" action="Index"/>
    <mvcSiteMapNode title="About" controller="Home" action="About"/>
  </mvcSiteMapNode>
</mvcSiteMap>

 

Menu Call:

@Html.MvcSiteMap().Menu()


Its just printing Home / Dashboard / My Profile / My Jobs

 

Here is my MenuHemperModel:

    <ul class="container_12" id="main-menu">
        @foreach (var node in Model.Nodes) { 
            <li class="home current">@Html.DisplayFor(m => node) 
                @if (node.Children.Any())
                {
                    @Html.DisplayFor(m => node.Children)
                }
           </li>
        }
    </ul>

The check for children produces no children... Looks like its because its already on a child node. Any ideas on what I need to pass into the Menu() call to get it to print the whole thing?

Thanks for offering to help

 

Feb 8, 2011 at 3:46 PM

I found similar behavior when I first started so what I do (might not be the best approach but works) is wrap everything in a parent that is insignificant then opt to not show starting node.

Constructor 14/14

@Html.MvcSiteMap("SiteNav").Menu("_TopNav", 1, true, false, 99, true, false)

 

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" enableLocalization="true">
  <mvcSiteMapNode title="SitemapRootDummy" clickable="false" changeFrequency="Always" updatePriority="Normal" key="SitemapRootDummy">
    <mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
      <mvcSiteMapNode title="Dashboard" controller="Home" action="Index"/>
      <mvcSiteMapNode title="My Profile" controller="Home" action="Index"/>
      <mvcSiteMapNode title="My Jobs" controller="Home" action="Index"/>
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Workplace" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
      <mvcSiteMapNode title="Jobs" controller="Home" action="Index"/>
      <mvcSiteMapNode title="Calendar" controller="Home" action="Index"/>
      <mvcSiteMapNode title="Customers" controller="Home" action="Index"/>
      <mvcSiteMapNode title="Equipment" controller="Home" action="Index"/>
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Reports" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
      <mvcSiteMapNode title="Reports" controller="Home" action="Index"/>
      <mvcSiteMapNode title="Search" controller="Home" action="Index"/>
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Settings" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
      <mvcSiteMapNode title="Control Panel" controller="Home" action="Index"/>
    </mvcSiteMapNode>
    <mvcSiteMapNode title="Support" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal">
      <mvcSiteMapNode title="Help" controller="Home" action="Index"/>
      <mvcSiteMapNode title="Feedback" controller="Home" action="Index"/>
      <mvcSiteMapNode title="About" controller="Home" action="About"/>
    </mvcSiteMapNode>
  </mvcSiteMapNode>
</mvcSiteMap>

 

 

@Html.MvcSiteMap("SiteNav").Menu("_TopNav", 1, true, false, 99, true, false)
Feb 8, 2011 at 4:04 PM

Thanks for the reply.

How were you able to explicitly name your template? I've just altered the MenuHelperModel.cshtml files so far...

Feb 8, 2011 at 4:22 PM

Just duplicate MenuHelperModel and make modifications. Mine is _TopNav.cshtml

Feb 8, 2011 at 4:23 PM
Edited Feb 8, 2011 at 4:25 PM

UPDATE

The Call:

 

@Html.MvcSiteMap().Menu(false, false, true)

 

Works on the original sitemap (without being wrapped in the dummy root node). The only problem is that selects the first node (Home) and its children, then doesn't bother with the rest (no Workplace, Reports or Support).

I don't know how much more of this I can take

Feb 8, 2011 at 4:40 PM

Have you got a custom provider sitting on top of all of this?

I tried your solution also, and couldn't get that to work. It only returns the root dummy node, and I played around with the parameters a bit. 

So I've been debugging my call:

@Html.MvcSiteMap().Menu(false, false, true)


And I can confirm that it only return ONE of the parent nodes and its 3 children. It doesn't bring back any of the parents siblings. hmmmm

Feb 9, 2011 at 10:34 AM

Ok, I've since found out A LOT overnight, and I've got it working how I want it to work

Basically there are a great deals about the core fundamentals of how sitemaps work that you really need to know before delving into a provider like this.

I'll write a blog post on it (hopefully this lunchtime) and will post a link to it when its done. Will be ideal for newbs hopefullu

Feb 10, 2011 at 2:32 PM

I've written a blog post which is a sort of tutorial into getting started with the MVC sitemap provider:

http://edspencer.me.uk/2011/02/10/mvc-sitemap-provider-tutorial/

Let me know if its missing anything or has any mistakes

Sep 20, 2011 at 6:36 PM

And now I've written a much more in depth tutorial.

Includes starting a solution from scratch, breadcrumbs and navigation.

http://edspencer.me.uk/2011/09/20/mvc-sitemap-provider-tutorial-2-breadcrumbs/