MvcSiteMapProvider MVC5 External URL Re-routing to Home Controller / Index Method

1.1k views Asked by At

I'm using MvcSiteMapProvider 4.6.18. Many of my menu items link to external sites; however, the "url" attribute of mvcSiteMapNode is not being carried over to the menu. That is, I can see the url in the source, but the link is referring to the parent mvcSiteMapNode controller and action and not the url I specified.

Here's the relevant code:

<?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-4.0"
  xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0 MvcSiteMapSchema.xsd">

<mvcSiteMapNode title="Home" controller="Home" action="Index">
    <mvcSiteMapNode title="About" url="http://www.amazon.com"/>
</mvcSiteMapNode>

</mvcSiteMap>

And here's what I see when viewing source:

<li>
    <a href="/"><span class="menu-text">About</span></a>
</li>

It doesn't matter what I use for the url, it always points to the root (i.e. Home).

There seems to be something simple that I'm missing. But for the life of me, I can't figure it out. For completeness, here's my RouteConfig:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Any help would be much appreciated.

Update

Thanks to @NightOwl888, the issue was with one of the display templates. The mvcSiteMapProvider was part of a bootstrap theme template I downloaded from wrapbootstrap and didn't think to look at the display templates as a possible issue.

Here's the offending template, modified from the original NuGet download to work with a custom side bar menu.

@model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel
@using System.Web.Mvc.Html
@using MvcSiteMapProvider.Web.Html.Models

<ul class="nav sidebar-menu">
   @ShowMenu(Model.Nodes)
</ul>

@helper ShowMenu(IEnumerable<SiteMapNodeModel> menuItems)
{
   foreach (var node in menuItems)
   {
      var nodeclass = "";
      if (node.IsCurrentNode)
      {
         nodeclass = "active";
      }
      if (node.Children.Any(n => n.IsCurrentNode))
      {
         nodeclass = "active open";
      }
      else if (node.Children.Any())
      {
         foreach (var c in node.Children)
         {
            if (c.Children.Any())
            {
               if (c.Children.Any(n => n.IsCurrentNode))
               {
                  nodeclass = "active open";
               }
            }
         }
      }
      <li class="@(!string.IsNullOrEmpty(nodeclass) ? Html.Raw(nodeclass) : null)">
         @if (node.Children.Any())
         {
            @Html.Bootstrap().SidebarMenuItem(node.Title, node.Area, node.Action, node.Controller).Icon(node.ImageUrl).IsDropDown();
         }
         else
         {
            @Html.Bootstrap().SidebarMenuItem(node.Title, node.Area, node.Action, node.Controller).Icon(node.ImageUrl);
         }
         @if (node.Children.Any())
         {
            <ul class="submenu">
               @ShowMenu(node.Children)
            </ul>
         }
      </li>
   }
}
1

There are 1 answers

3
NightOwl888 On BEST ANSWER

MvcSiteMapProvider is driven by HTML helpers. Since I cannot reproduce the problem with v4.6.18 and MVC5, I suspect that you have not added one to your view.

A typical case would be to add the menu HTML helper to your /Views/Shared/_Layout.cshtml page, as follows.

<div class="navbar-collapse collapse">
    @*<ul class="nav navbar-nav">
        <li>@Html.ActionLink("Home", "Index", "Home")</li>
        <li>@Html.ActionLink("About", "About", "Home")</li>
        <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
    </ul>*@
    @* Use the MvcSiteMapProvider Menu HTML helper *@
    @Html.MvcSiteMap().Menu()
    @Html.Partial("_LoginPartial")
</div>

TIP: If you update your MvcSiteMapProvider.Web package to version 4.6.18, the Bootstrap CSS classes will be output on the Menu HTML helper, so it will blend with the default MVC 5 theme. Run the command PM> Update-Package MvcSiteMapProvider.Web -Safe from the Package Manager Console to update.