<asp:SiteMapDataSource> Control

Coding navigation menu items inside the <asp:Menu> control works fine for small Web sites. Once a site grows to a large hierarchy of pages, though, it becomes more difficult to maintain the menu since it means editing the Web page itself. A better solution is to move the menu items to an external file where the menu can be maintained apart from the Web pages which use it.

A common way to maintain a site menu is as an external XML file. Since XML data has a natural hierarchical structure, it is compatible for representing the structure of a hierarchical menu. An XML menu file can be linked to an <asp:Menu> control and used in the same fashion as if the menu had been coded internally as part of the control.

An external site menu is known as a site map. It is made available to an <asp:Menu> control through an <asp:SiteMapDataSource> control, much in the same way as an AccessDataSource feeds data to a GridView, DetailsView, FormView, or other type of bound information display control. Its general format is shown below.

<asp:SiteMapDataSource id="id" Runat="Server"
  ShowStartingNode="False|True"
  SiteMapProvider="provider"
/>
Figure 12-13. General format for <asp:SiteMapDataSource> control.

The SiteMapDataSource looks for a special file named web.sitemap as containing an XML-encoded site menu. Then, the SiteMapDataSource control is associated with a Menu control through the latter's DataSourceID property. Outline coding for these two controls is shown below.

<asp:SiteMapDataSource id="SiteMap" Runat="Server/>

<asp:Menu id="NavigationMenu" Runat="Server"
  DataSourceID="SiteMap"
  ...
  />
Listing 12-12. Linking a SiteMapDataSource to a Menu control.

The Menu control is linked to the SiteMapDataSource control which is linked to the web.sitemap file. The result is that the file's XML menu becomes the Menu control's operational menu. Furthermore, any changes to the menu structure takes place in the web.sitemap file and is automatically reflected in the Menu control.

The web.sitemap File

The web.sitemap file represents a hierarchical menu coded in special XML syntax to produce a Web site map. The following code shows the site map for the menu structure used in previous examples.

<?xml version="1.0" ?>
<siteMap>

<siteMapNode>

  <siteMapNode title="Page 1" url="Page1.aspx">
    <siteMapNode title="Page 1-1" url="Page1-1.aspx"/>
    <siteMapNode title="Page 1-2" url="Page1-2.aspx"/>
  </siteMapNode>

  <siteMapNode title="Page 2" url="Page2.aspx">
    <siteMapNode title="Page 2-1" url="Page2-1.aspx"/>
    <siteMapNode title="Page 2-2" url="Page2-2.aspx"/>
  </siteMapNode>

  <siteMapNode title="Page 3" url="Page3.aspx">
    <siteMapNode title="Page 3-1" url="Page3-1.aspx"/>
    <siteMapNode title="Page 3-2" url="Page3-2.aspx">
      <siteMapNode title="Page 3-2-1" url="Page3-2-1.aspx"/>
      <siteMapNode title="Page 3-2-2" url="Page3-2-2.aspx"/>
    </siteMapNode>
  </siteMapNode>

</siteMapNode>

</siteMap>
Figure 12-14. Code for example web.sitemap file.

The XML file must contain a <siteMap> tag surrounding all content. Inside this tag is a single <siteMapNode> root-node tag within which additional <siteMapNode> tags represent the hierarchical structure of menu items. These items are given title attributes for the text labels that appear in the menu, along with url attributes giving the relative URL to the page. These URLs must be relative to the root directory (the virtual Web directory) of the Web site because the web.sitemap file must appear in the root Web directory.

Once this web.sitemap file is placed into the root Web directory, it is automatically located by the SiteMapDataSource control to provide a site menu for any <asp:Menu> control that links to it. In the following example, this technique is used to provide menu items for a Menu control that works identically to the previous hard-coded menus.

Figure 12-15. Imported navigation menu from web.sitemap file.

Code for the SiteMapDataSource and Menu controls is shown below. Since the root node of the web.sitemap file is a single enclosing <siteMapNode> tag without menu content, a ShowStartingNode="False" property is added to the SiteMapDataSource to skip this empty node when displaying the menu. Menu styles are applied in the same way as if the menu were coded as part of the Menu control.

<asp:SiteMapDataSource id="SiteMap" Runat="Server" 
  ShowStartingNode="False"/>

<asp:Menu id="NavigationMenu" Runat="Server"
  DataSourceID="SiteMap"
			
  StaticDisplayLevels="1"
  StaticMenuItemStyle-VerticalPadding="2"
  StaticMenuItemStyle-Font-Name="Verdana"
  StaticMenuItemStyle-Font-Size="9pt"
  StaticMenuItemStyle-ForeColor="#990000"
  StaticHoverStyle-BackColor="#707070"
  StaticHoverStyle-ForeColor="#FFFFFF"

  DynamicMenuStyle-HorizontalPadding="5"
  DynamicMenuStyle-VerticalPadding="2"
  DynamicMenuStyle-BackColor="#E0E0E0"
  DynamicMenuStyle-ForeColor="#990000"
  DynamicMenuStyle-BorderWidth="1"
  DynamicMenuStyle-BorderColor="#C0C0C0"
  DynamicMenuItemStyle-VerticalPadding="2"
  DynamicMenuItemStyle-Font-Name="Verdana"
  DynamicMenuItemStyle-Font-Size="9pt"
  DynamicMenuItemStyle-ForeColor="#990000"
  DynamicHoverStyle-BackColor="#707070"
  DynamicHoverStyle-ForeColor="#FFFFFF"
/>
Listing 12-13. Setting styles for a site map built from web.sitemap file.

Site Map Providers

There can be only a single web.sitemap file in the root Web directory. This restriction is reasonable since normally there is only one menu for a Web site. However, you may wish to store your XML menu file under a different file name or provide alternative site maps for the same site. When creating sites maps with different file names, they still must be stored in the root Web directory.

Assume, for instance, that instead of using web.sitemap for the above XML menu file you decide to save it as Menu.sitemap. You need to document this change in the web.config file that also is stored in the Web root directory. Recall that this file is used in companion with script debugging and has the following initial setup.

<!-- Web.Config Configuration File -->

<configuration>
  <system.web>
    <customErrors mode="Off"/>
  </system.web>
</configuration>
Listing 12-14. Code for web.config file.

The need is to define a new site map Provider in addition to the web.sitemap file. The following <sitemap> section is added to the <system.web> section of the web.config file.

<!-- Web.Config Configuration File -->

<configuration>
  <system.web>
    <customErrors mode="Off"/>

    <siteMap enabled="true">
      <providers>

        <add name="MenuProvider"
          type="System.Web.XmlSiteMapProvider, 
                System.Web,
                Version=2.0.3600.0, 
                Culture=neutral, 
                PublicKeyToken=b03f5f7f11d50a3a"
          siteMapFile="Menu.sitemap"/>

      </providers>
    </siteMap>

  </system.web>
</configuration>
Listing 12-15. Code for web.config file to define a new Provider for a site map.

A name is assigned to this added provider ("MenuProvider" in this example), and the name of the site map file is given in the siteMapFile attribute ("Menu.sitemap" in this example). The type attribute is coded as shown.

Once this change is made to the web.config file, a SiteMapDataSource control points to this newly defined provider through its SiteMapProvider property, giving its assigned name. The coding change for the above example site to use this provider is shown below.

<asp:SiteMapDataSource id="SiteMap" Runat="Server"
  SiteMapProvider="MenuProvider"
  ShowStartingNode="False"/>

<asp:Menu id="NavigationMenu" Runat="Server"
  DataSourceID="SiteMap"
  ...
  />
Listing 12-16. Code to use a site map Provider defined in the web.config file.

As long as there is only one site map for a Web site it is not necessary to change from the default web.sitemap file. However, different site map providers are needed if different menu systems are used for different areas of your Web site.