MVC Sitemap show only parent nodes - asp.net

I want show only my parent nodes in my View.
This is my 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">
<mvcSiteMapNode title="About" controller="Home" action="About"/>
<mvcSiteMapNode title="Contact" controller="Home" action="Contact"/>
</mvcSiteMapNode>
<mvcSiteMapNode title="Test" controller="Test" action="Index">
<mvcSiteMapNode title="Teste2" controller="Test" action="Index"/>
<mvcSiteMapNode title="Teste3" controller="Test" action="Index"/>
</mvcSiteMapNode>
</mvcSiteMap>
How can I use the html helper #Html.MvcSiteMap().Menu() to show only the parent nodes, and only the child nodes?
Like this:
Parents:
Home
Test
Childs
About
Contacts
Teste2
Teste3
Thanks.

Try for top level
#Html.MvcSiteMap().Menu(0, true, false, 1)
Second level
#Html.MvcSiteMap().Menu(2, 1, true)
This tutorial may help

Related

MVCSiteMapProvider ignore parameters

I am using MVCSiteMapProvider.MVC5 and I am trying to set up my site map.
My routes are:
notifications/
notifications/Alarm/
notifications/Warning/
notifications/Information/
The Alarm, Warning and Information are passed to the "notificationFilter" action parameter.
This is my basic site map which currently shows by breadcrumb for route notifications/ as Home>Notifications.
<mvcSiteMapNode title="Home" controller="Dashboard" action="System">
<mvcSiteMapNode title="Vacuum Management" controller="Dashboard" action="SubSystem" />
<mvcSiteMapNode title="Notifications" controller="Notifications" action="SystemNotifications" />
</mvcSiteMapNode>
What I would like to do is add a catch all so that if the "notificationFilter" parameter is passed (e.g. notifications/Alarm/) it still displays the breadcrumb as Home>Notifications and ignores the parameter.
I have tried this:
<mvcSiteMapNode title="Home" controller="Dashboard" action="System">
<mvcSiteMapNode title="Vacuum Management" controller="Dashboard" action="SubSystem" />
<mvcSiteMapNode title="Notifications" controller="Notifications" action="SystemNotifications" notificationFilter="Alarm" />
Which works for notifications/Alarm but then nothing else. I also tried adding multiple lines:
<mvcSiteMapNode title="Home" controller="Dashboard" action="System">
<mvcSiteMapNode title="Vacuum Management" controller="Dashboard" action="SubSystem" />
<mvcSiteMapNode title="Notifications" controller="Notifications" action="SystemNotifications" notificationFilter="Alarm" />
<mvcSiteMapNode title="Notifications" controller="Notifications" action="SystemNotifications" notificationFilter="Warning" />
<mvcSiteMapNode title="Notifications" controller="Notifications" action="SystemNotifications" notificationFilter="Information" />
But because the title is the key the the bread crumb would display different text.
All help appreciated.
Thanks in advance!
Route Config:
routes.MapRoute(
name: "NotificationsSystem",
url: "notifications",
defaults: new { controller = "Notifications", action = "SystemNotifications", notificationFilter = "" }
);
routes.MapRoute(
name: "NotificationsSystemFiltered",
url: "notifications/{notificationFilter}",
defaults: new { controller = "Notifications", action = "SystemNotifications", notificationFilter = "" }
);
As per the documentation, getting a single node to match any value for a particular parameter can be done by using preservedRouteParameters.
<mvcSiteMapNode title="Notifications" controller="Notifications" action="SystemNotifications" preservedRouteParameters="notificationFilter" />
This works well when your node has no children, but if you put this attribute on nodes that do have children you need to take into consideration what will happen when the user navigates back up the hierarchy.

How do I create multiple different layouts using only one SiteMap?

Suppose I have 3 areas on my page that have links
Header
Menu
Footer
Each have different links, but some links overlap:
I am using MVCSiteMapProvider to accomplish this. I have a SiteMap:
<?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="false">
<mvcSiteMapNode title="Home" controller="Home" action="Index">
<mvcSiteMapNode title="Link 1" controller="" action="" visibility="Header, Footer" />
<mvcSiteMapNode title="Link 2" controller="" action="" visibility="Menu" />
<mvcSiteMapNode title="Link 3" controller="" action="" visibility="Header, Menu" />
<mvcSiteMapNode title="Link 4" controller="" action="" visibility="Menu, Footer, Header" />
</mvcSiteMapNode>
</mvcSiteMap>
I thought that maybe Visibility was the way to do this, but it doesn't work the way I want it.
Public Class MenuVisibilityProvider
Implements ISiteMapNodeVisibilityProvider
Public Function IsVisible(ByVal node As SiteMapNode, ByVal context As HttpContext, ByVal sourceMetadata As IDictionary(Of String, Object)) As Boolean Implements ISiteMapNodeVisibilityProvider.IsVisible
Dim visibility As String = node("visibility")
If visibility IsNot Nothing Then Return True
Select Case visibility
Case "Menu"
Case "Header"
Case "Footer"
Return True
End Select
Return False
End Function
End Class
I end up with all of the links in every area.
Edit for clarification:
This is a similar question, but also with no answer:
https://stackoverflow.com/questions/12845929/how-to-show-partial-site-map-including-current-node-with-mvcsitemapprovider
Also similar, but I don't want to have to make multiple SiteMaps: Using Multiple MvcSiteMaps
OP here. I accomplished this using only one site map.
To do this:
I added visibility tags to each sitemap element, for example:
<mvcSiteMapNode title="Login" controller="Members" action="Login" visibility="SideMenu Footer" />
In this example "SideMenu Footer" are my tags. I will use String.Contains() later to determine visibility.
I added multiple different siteMap providers in the Web.config with different siteMapNodeVisibilityProvider:
<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" />
<add name="NavSiteMapProvider" ... siteMapNodeVisibilityProvider="RootNamespace.Namespace.NavVisibilityProvider, RootNamespace" ... />
<add name="FooterSiteMapProvider" ... siteMapNodeVisibilityProvider="RootNamespace.Namespace.FooterVisibilityProvider, RootNamespace" ... />
</providers>
</siteMap>
I created a new code file (class) called CustomVisibilityProvider. Inside I created a class for each provider (Footer, Nav, Menu etc)
' Note: VB.NET :P
Public Class MenuVisibilityProvider
Implements ISiteMapNodeVisibilityProvider
Public Function IsVisible(ByVal node As SiteMapNode, ByVal context As HttpContext, ByVal sourceMetadata As IDictionary(Of String, Object)) As Boolean Implements ISiteMapNodeVisibilityProvider.IsVisible
Dim visibility As String = node("visibility")
If visibility Is Nothing Then Return False
If visibility.Contains("Menu") Then Return True
Return False
End Function
End Class
Public Class NavVisibilityProvider
Implements ISiteMapNodeVisibilityProvider
...
If visibility.Contains("Nav") Then Return True
...
End Class
When you're in a view file:
#Html.MvcSiteMap("FooterSiteMapProvider").Menu
Note: You can give the Menu() a custom view also, so that nav, footer, menu etc render the links differently (some might be in <ul></ul> format while others might be <a> tags).

.net Menu control SelectedItem always null on homepage

I am using a .net webforms Menu control generated from the following sitemap:
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="" title="NavigationWrapper" description="">
<siteMapNode url="/" title="Home" description="" />
<siteMapNode url="/search" title="Search" description="" />
<siteMapNode url="/contact" title="Contact" description="" />
</siteMapNode>
</siteMap>
When I click the home link, the SelectedItem property of the menu control is always null, but it works fine when clicking the other two links. I can't seem to work out why!
The only way I can seem to get around this is to create a www.abc.com/home link for my homepage, but I'd prefer not to do that.
Any help much appreciated!
Edit:
Route Collection is as follows:
routes.MapPageRoute("Home", "", "~/Default.aspx");
routes.MapPageRoute("Search", "search", "~/SearchByMap.aspx");
routes.MapPageRoute("contact", "contact", "~/Contact.aspx");
Try this:
<siteMapNode url="~/" title="Home" description="">
<siteMapNode url="/search" title="Search" description="" />
<siteMapNode url="/contact" title="Contact" description="" />
</siteMapNode>
Add this to your route collection:
public static void RegisterRoutes(RouteCollection routeCollection)
{
routeCollection.MapPageRoute("Home", "", "~/Default.aspx");
}

Breadcrumbs SiteMapPath and SEO-Friendly Routing

I have routing set up as follows:
void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("", "Home", "~/Default.aspx");
......
}
I'm implementing breadcrumbs using a SiteMapPath control:
<asp:SiteMapPath ID="SiteMapPath1" CssClass="breadCrumbs" runat="server">
</asp:SiteMapPath>
Web.sitemap is set up as follows:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="Home" title="Home" description="Home">
<siteMapNode url="~/About" title="About" description="About">
<siteMapNode url="~/History" title="History"
description="History" />
</siteMapNode>
</siteMapNode>
</siteMap>
My problem is that when I navigate to mysite.com instead of mysite.com/default.aspx, the Home breadcrumb node does not appear. What am I missing?
UPDATE
I managed to get the "Home" node to display by updating Web.sitemap as follows:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="Home" title="Home" description="Home">
<siteMapNode url="~/Default.aspx" title="" description="" />
<siteMapNode url="~/About" title="About" description="About">
<siteMapNode url="~/History" title="History"
description="History" />
</siteMapNode>
</siteMapNode>
</siteMap>
The only remaining problem is that the path separator is still displaying on home page for mysite.com
Is there a way to programatically render the separator invisible for the home page? The SiteMapPath control itself is in a master page.
Maybe you should change your sitemap file as follows :
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/" title="Global Site Name or Welcome Message" description="Home">
<siteMapNode url="~/Home" title="Home" description="" />
<siteMapNode url="~/About" title="About" description="About">
<siteMapNode url="~/History" title="History"
description="History" />
</siteMapNode>
</siteMapNode>
</siteMap>
and from the sitemapdatasource you should set ShowStartingNode="false" and I think that this solves both of your problems at once...
NOTE: of course this will require that you made this change in the global.asax file (VB):
RouteTable.Routes.MapPageRoute("Home0", "", "~/Default.aspx", True)
RouteTable.Routes.MapPageRoute("Home1", "Home", "~/Default.aspx", True)
hope this helps...

How do I make a sitemap based menu in asp.net with onl top level elements?

I'm trying to make a menu based off of an asp.net sitemap. How do you nest the sitemap nodes so that they all appear on the same level. Here is what I have:
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode>
<siteMapNode url="~/Default.aspx" title="Home" description="link to Home" />
<siteMapNode url="~/about.aspx" title="About" description="abot" />
</siteMapNode>
</siteMap>
Here is what the code for the Menu control looks like:
<asp:Menu ID="Menu1" runat="server" BackColor="#E3EAEB"
DataSourceID="SiteMapDataSource1"
</asp:Menu>
They both appear as 2nd tier elements underneath an arrow. Sorry for the beginner question but I've never used the menu control before.
You just need to set the StaticDisplayLevels and only have one level in the sitemap file.
<asp:Menu runat="server" DataSourceID="SiteMapDataSource" StaticDisplayLevels="2" >
</asp:Menu>
An example of the web.sitemap:
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode>
<siteMapNode url="Default.aspx" title="Home" description="" />
<siteMapNode url="Page2.aspx" title="Page2" description="" />
</siteMapNode>
</siteMap>

Resources