Shimmy Weitzhandler
Shimmy Weitzhandler

Reputation: 104741

Can't get DynamicNodeProvider to work

I followed the instructions described here, but no menu is generated.

I added the following to my _Layout.cshtml file:

@Html.MvcSiteMap().Menu();

What happens is the static links in the Mvc.sitemap file are shown in the menu. But the DynamicSiteMap nodes don't, furthermore I placed a breakpoint in the DynamicNodeProviderBase.GetDynamicNodeCollection method and it doesn't stop there.

I'm pretty new to MVC so it might be an obvious solution, what could I be missing?

Check out more about this issue here.

Update:

I also tried to generate a breadcrumb (calling @Html.MvcSiteMap().SiteMapPath()) and nothing was generated and that method mentioned above wasn't called at all.

My idea is to make a menu/sitemap that is purely generated and controllable by the application, no static menuitems or nodes all.

Update

I'm also trying to use attributes as described here and it doens't work:

[MvcSiteMapNodeAttribute(Title = "Checkout complete", ParentKey = "Checkout")]

Upvotes: 1

Views: 1725

Answers (1)

Petar Vučetin
Petar Vučetin

Reputation: 3615

This should work just fine. Make sure that your web.config looks something like this:

      <siteMap defaultProvider="MvcSiteMapProvider" enabled="true">
          <providers>
            <clear />
            <add name="MvcSiteMapProvider" 
                 type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" 
                 siteMapFile="~/Mvc.Sitemap" securityTrimmingEnabled="true" cacheDuration="5" 
                 enableLocalization="true" scanAssembliesForSiteMapNodes="true" includeAssembliesForScan="" 
                 excludeAssembliesForScan="" attributesToIgnore="visibility" 
                 nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider" controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider" actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider" aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider" siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider" siteMapNodeVisibilityProvider="MvcSiteMapProvider.DefaultSiteMapNodeVisibilityProvider, MvcSiteMapProvider" siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider" />
          </providers>
        </siteMap>

The important bit is the siteMapFile is correctly setup. Also, make sure that in your .sitemap file (in my case Mvc.Sitemap) is setup correctly:

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0"
            xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0 MvcSiteMapSchema.xsd"
            enableLocalization="true">

  <mvcSiteMapNode title="Home" controller="Home" action="Index">
    <mvcSiteMapNode title="About" controller="Home" action="About"/>
      <mvcSiteMapNode
      title="Details"
      action="Present"
      dynamicNodeProvider="MvcApplication3.ItemDetailsDynamicNodeProvider, MvcApplication3" />
  </mvcSiteMapNode>

</mvcSiteMap>

The important bit here is that dynamicNodeProvider type and assembly are spelled correctly and located correctly.

Here is the ItemDetailsDynamicNodeProvider for completeness

public class ItemDetailsDynamicNodeProvider : DynamicNodeProviderBase
    {
        public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
        {
            var repository = new Repository();

            foreach (var item in repository.GetItems())
            {
                var node = new DynamicNode(item.Slug, item.DisplayName);
                node.RouteValues.Add("id", item.Slug);

                System.Diagnostics.Debug.WriteLine(item.Slug);

                yield return node;
            }
        }
    }

    public class Repository
    {
        public IEnumerable<Something> GetItems()
        {
            yield return new Something { Slug = "Slug1", DisplayName = "DisplayName1"};
            yield return new Something { Slug = "Slug2", DisplayName = "DisplayName2" };
        }
    }

    public class Something
    {
        public string Slug { get; set; }
        public string DisplayName { get; set; }
    }

Upvotes: 2

Related Questions