asp.net-mvcrazormvcsitemapproviderasp.net-mvc-sitemap

MVCSiteMapProvider Dynamic Node always returns the first node for all pages in the breadcrumbs


I'm using the MVCSitemapProvider for my ASP.NET MVC 3 project, I have a dynamic node for a press release section. The issue I'm facing is that there are multiple nodes for a section and when I look at the site map it's working correctly as so:

> Home
  > Static Node - Press Releases
    >Dynamic node - Press Release #1
    >Dynamic node - Press Release #2
    >Dynamic node - Press Release #3

However in the bread crumbs, if I navigate to the Press Release #2 page. the Breadcrumb will show the first node.

Home > Press Releases > Press Release #1 

Here's the code for the Node Provider

public class PressReleaseDynamicNodeProvider : DynamicNodeProviderBase {

    public PressReleasesRepository _repository = new PressReleasesRepository();
    public List<PressRelease> releases = new List<PressRelease>();

    public override IEnumerable<DynamicNode> GetDynamicNodeCollection() {
        releases = _repository.GetPressReleases();
        var returnValue = new List<DynamicNode>();

        foreach (var release in releases) {
            DynamicNode node = new DynamicNode();
            node.Title = release.Title;
            returnValue.Add(node);
        }
        return returnValue;
    }

}

and the MVC sitemap code:

<mvcSiteMapNode controller="News" action="PressReleases" title="Press Releases" >
  <mvcSiteMapNode controller="News" action="PressRelease" title="" dynamicNodeProvider="MySite.NodeProvider.PressReleaseDynamicNodeProvider, MySite" />
</mvcSiteMapNode>

As I was rewriting this quesiton, I've been playing around with the code, not making any major changes and NOW... Press Release #1 is showing Press Release #1, Press Release #2 is showing Press Release #3 and Press Release #3 is showing Press Release #1.

I'm baffled by this.


Solution

  • The reason for this is that the sitemap provider can't distinguish between your routes. Right now all press releases are accessed through the same URL, /news/pressreleases/. To make the breadcrumbs correct you should pass something like an id, to the provider through node.RouteValues.

    For example, your action method PressReleases in NewsControllermay look something like this:

    public ActionResult PressReleases(int id) {
      ... implementation ...
    }
    

    Then you would pass the id parameter into the RouteValues like this:

    foreach (var release in releases) {
      DynamicNode node = new DynamicNode();
      node.Title = release.Title;
      node.RouteValues.Add("id", release.Id);
      returnValue.Add(node);
    }
    

    This small change will make the breadcrumbs work as expected.