<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

Control Visible Menus with web.sitemap

Published on
20,475 Points
10,875 Views
1 Endorsement
Last Modified:
Awarded
A quick way to get a menu to work on our website, is using the Menu control and assign it to a web.sitemap using SiteMapDataSource.

Example of web.sitemap file:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
     <siteMapNode  url="~/" title="Home"  description="Home">
         <siteMapNode url="" description="Menu 1" title="Menu 1">
             <siteMapNode url="" description="SubMenu 1" title="Sub Menu 1"/>
         </siteMapNode>
         <siteMapNode url="" description="Menu 2" title="Menu 2"/>
         <siteMapNode url="" description="Menu 3" title="Menu 3"/>
     </siteMapNode>
</siteMap>

Open in new window

Sample code to add to the page menu:
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu"
      EnableViewState="False" IncludeStyleBlock="False" Orientation="Horizontal"
      DataSourceID="SiteMapDataSource1">
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server"  ShowStartingNode="false" />

Open in new window

Running the application, we will have something like the next picture:
 menu1rc.png
To show or hide the menu depending on the type of access each user, we may define the Roles in each SiteMapNode.

Another way to control the menus visible, is to add an attribute in each SiteMapNode and depending on its value, or will not display each menu.

For this, the web.sitemap will be something like:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
     <siteMapNode  url="~/" title="Home"  description="Home" visible="true">
         <siteMapNode url="" description="Menu 1" title="Menu 1" visible="true">
             <siteMapNode url="" description="SubMenu 1" title="Sub Menu 1" visible="true"/>
         </siteMapNode>
         <siteMapNode url="" description="Menu 2" title="Menu 2" visible="true"/>
         <siteMapNode url="" description="Menu 3" title="Menu 3" visible="true"/>
     </siteMapNode>
</siteMap>

Open in new window

The attribute "visible" is that we will indicate whether or not the menu is shown, and we'll add the event MenuItemDataBound on Menu with the following code:
protected void NavigationMenu_MenuItemDataBound(object sender, MenuEventArgs e)
{     SiteMapNode node = e.Item.DataItem as SiteMapNode;
     if (!string.IsNullOrEmpty(node["visible"]))
     {
         bool isVisible;
         if (bool.TryParse(node["visible"], out isVisible))
         {
             if (!isVisible)
             {
                 if (e.Item.Parent != null)
                     e.Item.Parent.ChildItems.Remove(e.Item);
                 else
                     ((Menu)sender).Items.Remove(e.Item);
             }
         }
     }
}

Open in new window

Thus, we have our menu to show all nodes whose attribute value equals True.

To be able to directly control the menus that will be visible or not, I used a Treeview to bind the web.sitemap file and set all items to show a checkbox, which will indicate the status of the Visible attribute.
<asp:TreeView runat="server" ID="tvMenus" AutoGenerateDataBindings="False" DataSourceID="XmlDsSiteMap"
     OnTreeNodeCheckChanged="tvMenus_TreeNodeCheckChanged" ShowCheckBoxes="All" ShowLines="True"
     OnTreeNodeDataBound="tvMenus_TreeNodeDataBound">
     <DataBindings>
         <asp:TreeNodeBinding DataMember="siteMapNode" SelectAction="None" ShowCheckBox="True"
             TextField="title" />
         <asp:TreeNodeBinding DataMember="siteMapNode" TextField="title" />
         <asp:TreeNodeBinding DataMember="siteMapNode" TextField="title" />
         <asp:TreeNodeBinding DataMember="siteMap" />
     </DataBindings>
</asp:TreeView>
<asp:XmlDataSource ID="XmlDsSiteMap" runat="server" DataFile="~/Web.sitemap" XPath="/*/*/*">
</asp:XmlDataSource>

 

protected void tvMenus_TreeNodeDataBound(object sender, TreeNodeEventArgs e)
{     XmlElement node = e.Node.DataItem as XmlElement;
     if (node.Attributes["visible"] != null)
     {         if (!string.IsNullOrEmpty(node.Attributes["visible"].Value))
         {
             bool isVisible;
             if (bool.TryParse(node.Attributes["visible"].Value, out isVisible))
             {
                 e.Node.Checked = isVisible;
             }
             else
                 e.Node.Checked = true;
         }
         else
             e.Node.Checked = true;
     }
}

Open in new window

menu2f.png
Finally, to record the attribute changes depending on the state of the checkbox, we added to the Treeview TreeNodeCheckChanged event the following code:
protected void tvMenus_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
{     XmlDsSiteMap.GetXmlDocument().SelectSingleNode(e.Node.DataPath)
               .Attributes["visible"].Value = e.Node.Checked.ToString();
}

And we add the button to save the changes the following code:

protected void btn_Click(object sender, EventArgs e)
{     XmlDsSiteMap.Save();
}

Open in new window

Now just enable and disable these items like we want to.
 menu3x.png
This is a very simple way to allow your application users control each Menu visibility and avoid to change the web.sitemap manually.
You may have to make some changes in order to adjust to your requirements, but this is a good point.
1
Comment
0 Comments

Featured Post

OWASP: Avoiding Hacker Tricks

Learn to build secure applications from the mindset of the hacker and avoid being exploited.

Join & Write a Comment

Did you know PowerShell can save you time with SaaS platforms? Simply leverage RESTfulAPIs to build your own PowerShell modules. These will kill repetitive tickets and tabs, using the command Invoke-RestMethod. Tune into this webinar to learn how…
Microsoft Office 365 Backup and Restore Solution by SysTools to export Office 365 mailbox to PST / EML file format on Windows OS. On Mac, tool backup O365 to PST / MBOX / MSG / EML / EMLX file formats. Not only this, restore option helps to import s…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month