Application Security Testing: An Integral Part of DevOps
Every Web site needs to display navigation data that guides its users through the site. ASP.NET 2.0 provides excellent site-navigation features that provide very simple ways of storing and displaying site-navigation data in your Web applications. Apart from that, a site navigation API also provides a provider-based programming abstraction for accessing site navigation data. This article examines these new site-navigation features and explains how to take advantage of them in your Web applications. Along the way, it demonstrates how the new site-navigation controls that are built on top of the Site Navigation classes, such as the Menu, TreeView, SiteMapPath, and SiteMapDataSource controls, consume and display navigation data without being aware of data-store-specific storage issues.
Site Navigation Structure and the Controls
You represent the navigation structures for a Web site through a file called web.sitemap. The Web.sitemap file contains a single top-level siteMap element. Nested within the siteMap element is at least one siteMapNode element. A site map must always contain a top-level siteMapNode. The Site Navigation feature requires a single root siteMapNode to ensure that you will always converge on a single well-known node when walking up through the hierarchy of the nodes. You can nest as many siteMapNode elements beneath the root siteMapNode element as needed. Additionally, you can nest siteMapNode elements to any arbitrary depth.
The siteMapNode element usually contains the Url, Title, and Description attributes:
- The Url attribute indicates a virtual path that corresponds to a page in your application. It can also contain paths to pages in other applications, or URLs that point at completely different Web sites. You should use relative paths when specifying the Urls in the web.sitemap file.
- The Title attribute displays the textual content when rendering the UI for navigational data. For example, the SiteMapPath control uses the Title attribute to display the text of the hyperlinks in the control.
- If the siteMapNode contains a Description attribute, you use that information to display tooltips or ALT text.
Once you have the site-navigation structure available in the web.sitemap file, you then can consume that information by using the following two steps:
- Add a SiteMapDataSource control to your page. This control will automatically consume the contents of the web.sitemap file and make it readily available for the hierarchical data bound controls.
- Bind the data bound controls such as SiteMapPath, TreeView, and Menu to the SiteMapDataSource control and then display the site navigation information.
Now that you understand the procedures involved in displaying the site navigation information, it's time to briefly define the graphical site navigation controls:
- SiteMapPath—This is a breadcrumb control that retrieves the user's current page and displays the hierarchy of pages. Since the entire hierarchy is displayed through this control, it enables the users to navigate back to other pages in the hierarchy. SiteMapPath works exclusively with the SiteMapDataSource control.
- TreeView—This control provides a vertical user interface to expand and collapse selected nodes on a Web page, as well as providing check box functionality for selected items. By setting the SiteMapDataSource control as the data source for the TreeView control, you can leverage the automatic data binding capabilities of the TreeView control.
- Menu—This control provides a horizontal or vertical user interface that also can display additional sub-menus when a user hovers over an item. When you use the SiteMapDataSource control as the data source, data binding will be automatic.
Now that you have seen the different controls, follow an example that exercises these controls.
Displaying Site Navigation Data from the Web.sitemap File
This example uses the TreeView control to display hierarchical information about the site structure by using the contents of the web.sitemap file. It creates a new ASP.NET Web Site named SiteNavigation and then adds a new web.sitemap file to the site. The web.sitemap file looks as follows:
<?xml version="1.0" encoding="utf-8" ?> <siteMap> <siteMapNode title="Default" description="Home" url="Default.aspx" > <siteMapNode title="Members" description="Members" url="Members.aspx">> <siteMapNode title="My Account" description="My Account" url="MyAccount.aspx" /> <siteMapNode title="Products" description="Products" url="Products.aspx" /> </siteMapNode> <siteMapNode title="Administration" description="Administration" url="~/Admin/Default.aspx"> <siteMapNode title="Customer" description="Customer Admin" url="~/Admin/Customer/default.aspx" /> <siteMapNode title="Products Admin" description="Products Admin" url="~/Admin/ProductsAdmin.aspx" /> </siteMapNode> </siteMapNode> </siteMap>
As you can see, the web.sitemap file specifies the list of nodes that specify the navigation structure of the site, which can be completely independent of the site folder layout or other structures.
Create a new master page named Navigation.master and modify its code to look like the following:
<%@ Master Language="C#" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Master Page</title> </head> <body> <form id="form1" runat="server"> <div> <table style="width: 100%; height: 100%" border="1"> <tr> <td style="width: 10%"> <asp:TreeView ID="TreeView1" Runat="server" DataSourceID="SiteMapDataSource1" ExpandDepth="2" ShowExpandCollapse="False" NodeIndent="10"> <LevelStyles> <asp:TreeNodeStyle Font-Bold="True" Font-Underline="False"/> <asp:TreeNodeStyle Font-Italic="True" Font-Underline="False" /> <asp:TreeNodeStyle Font-Size="X-Small" ImageUrl="~/Images/bullet.gif" Font-Underline="False" /> </LevelStyles> <NodeStyle ChildNodesPadding="10" /> </asp:TreeView> </td> <td style="width: 100px"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> </asp:contentplaceholder> </td> </tr> </table> <asp:SiteMapDataSource ID="SiteMapDataSource1" Runat="server"/> </div> </form> </body> </html>
As you can see, the code places SiteMapDataSource control in the page and uses it as the data source control for the treeview named TreeView1. The TreeView control also defines the styles for the different node levels. In this example, because you have a SiteMapDataSource placed on the page, it will specifically look for a file with the name web.sitemap by default. It will read the contents of the web.sitemap file and consume that information as a data source control.
Once the information is available in a SiteMapDataSource control, you then can consume it from a data-bound control. In this example, you used the TreeView control as a data-bound control and set the DataSourceID property of the TreeView control to the ID value of the SiteMapDataSource.
Now that you have created the master page, you can create a content page that inherits the contents from it. Create a content page named Default.aspx and modify its code to look like the following:
<%@ Page Language="C#" MasterPageFile="~/Navigation.master" Title="Default Page"%> <asp:Content ContentPlaceHolderID="ContentPlaceHolder1" ID="Content1" Runat="Server"> This is the default page </asp:Content>
The code combines the master page and the content page and then inserts contents in appropriate locations by using the asp:Content element. You simply have some text information that indicates that this content is coming from the default page. If you execute the above code, you will see an output that is somewhat similar to Figure 1.
Figure 1. Default Page Output
The left navigation contents in Figure 1 are produced by the master page, and the main body of the page is produced by default.aspx. Clicking on any of the hyperlinks in the treeview takes you to the page url that is specified in the web.sitemap file.