|
|
|
|
A First Look at ASP.NET v.2.0
Last Updated 2/3/2009 3:43:01 PM
Site Map Configuration Files
The XmlSiteMapProvider defines a set schema for the app.SiteMap file, as shown in Listing 5.10.
Listing 5.10. XmlSiteMapProvider Schema
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="siteMap">
<xs:complexType>
<xs:sequence>
<xs:element ref="siteMapNode"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="siteMapNode">
<xs:complexType>
<xs:sequence>
<xs:element ref="siteMapNode" minOccurs="0"
>MaxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="url" type="xs:string"/>
<xs:attribute name="title" type="xs:string"/>
<xs:attribute name="description" type="xs:string"/>
<xs:attribute name="keywords" type="xs:string"/>
<xs:attribute name="roles" type="xs:string"/>
<xs:attribute name="SiteMapFile" type="xs:string"/>
<xs:attribute name="Provider" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:schema>
|
This defines a structure consisting of a root siteMap element, with the site structure being contained by siteMapNode elements. There has to be one top-level siteMapNode element, and within that can be any number of siteMapNode elements of any depth. The attributes for the siteMapNode element are shown in Table 5.4.
The use of SiteMapFile allows the site map information to be split among different sources. This is especially useful when different divisions supply sections of a corporate siteeach part of the site map can be authored independently and even stored in different providers.
Listing 5.11 shows a sample site map file. To create one within Visual Studio .NET "Whidbey," you simply create a new XML file and call it app.SiteMapthere isn't a template for this.
Listing 5.11. Sample app.SiteMap File
<siteMap>
<siteMapNode title="Home"
description="Home"
url="SiteMaps.aspx?id=1">
<siteMapNode title="Sales"
description="The Sales Site"
url="SiteMaps.aspx?id=2">
<siteMapNode title="Customers"
url="SiteMaps.aspx?id=3"/>
<siteMapNode title="Products"
url="SiteMaps.aspx?id=4/>
<siteMapNode title="Region"
url="SiteMaps.aspx?id=5"/>
<siteMapNode title="Futures"
url="SiteMaps.aspx?id=6"/>
</siteMapNode>
<siteMapNode title="Research"
description="The Research Site"
url="SiteMaps.aspx?id=7">
<siteMapNode title="Widgets"
url="SiteMaps.aspx?id=8"/>
<siteMapNode title="Doodads"
url="SiteMaps.aspx?id=9"/>
<siteMapNode title="Thingies"
url="SiteMaps.aspx?id=10" />
</siteMapNode>
</siteMapNode>
</siteMap>
|
This provides the following structure for the site:
Home
Sales
Customers
Products
Region
Futures
Research
Widgets
Doodads
Thingies
Using a Site Map File
>Once the structure of your site is defined in the site map file, you then need a way to make use of it. For this you use a SiteMapDataSource control, which provides data access to the site map data, and then a control to display that data. From within Visual Studio .NET "Whidbey," you can just drag a SiteMapDataSource control onto the design surfacethere's no need to set any properties because it defaults to using app.SiteMap as its data source. You can then drag a TreeView control onto the page and set its DataSourceId property to the .id of the SiteMapDataSource control. Figure 5.11, for example, shows how our Big Corp site could be constructed using a single menu.
Other controls can be bound to site map data, but in the Technology Preview release, the TreeView provides the best option because of its hierarchical display. It's possible that a dedicated menu control will appear in future versions.
Site Maps in Depth
At its simplest, the use of site maps needs nothing more than has been discussed above, but there's actually more to them. Adding a SiteMapData Source control to a page provides all that's needed for site map handling, but there are properties that allow for more control over how the data is supplied from the SiteMapDataSource to controls. For example, the syntax of the SiteMapDataSource control is shown in Listing 5.12.
Listing 5.12. SiteMapDataSource Syntax
<asp:SiteMapDataSource id="String" runat="server"
FlatDepth="Integer"
SiteMapProvider="String"
SiteMapViewType="[Flat|Path|Tree]"
StartingDepth="Integer"
StartingNodeType="[Current|Parent|Root]"
StartingNodeUrl="String"
/>
|
The attributes are shown in Table 5.5.
The effects of some of these properties are not immediately apparent and depend on which control you bind to the data source and where you are in the navigation hierarchy. Probably the most useful control is the TreeView, which naturally displays hierarchical data, but the ListBox is also good for displaying site map data in a flat view. A good way to see the effects of these properties is to build a grid with three SiteMapDataSource controls, each set to a different SiteMapViewType. Then you can bind a TreeView and a ListBox to each type view of the site map, as shown in Listing 5.13.
Listing 5.13. Sample Site Map Displays
<asp:SiteMapDataSource id="SiteDataFlat" runat="server"
SiteMapViewType="Flat" />
<asp:SiteMapDataSource id="SiteDataPath" runat="server"
SiteMapViewType="Path" />
<asp:SiteMapDataSource id="SiteDataTree" runat="server"
SiteMapViewType="Tree" />
<table border="1" width="50%">
<tr>
<td>Flat</td>
<td>Path</td>
<td>Tree</td>
</tr>
<tr>
<td>
<asp:TreeView runat="server"
DataSourceId="SiteDataFlat" />
</td>
<td>
<asp:TreeView runat="server"
DataSourceId="SiteDataPath" />
</td>
<td>
<asp:TreeView runat="server"
DataSourceId="SiteDataTree" />
</td>
</tr>
<tr>
<td>
<asp:ListBox runat="server"
DataSourceId="SiteDataFlat" />
</td>
<td>
<asp:ListBox runat="server"
DataSourceId="SiteDataPath" />
</td>
<td>
<asp:ListBox runat="server"
DataSourceId="SiteDataTree" />
</td>
</tr>
</table>
|
The initial display is shown in Figure 5.12. By default the TreeView binds the title attribute of the site map to the Text property and the url attribute to the NavigateUrl property, giving you an instant menu control. For the ListBox the title attribute is bound to both the DataTextField and DataValueField properties.
You can see from this that when in Tree mode, the TreeView displays as you expect it to. However, the Flat view shows how all nodes (at whatever level) are shown. Nodes with children are expandable in the normal TreeView style. For the Path mode, nothing is shown because we haven't yet performed any navigation.
For the ListBox control, the Tree mode shows only the first node because it is a naturally flat control and can deal only with a single level of the hierarchy. However, in Flat mode you see all nodes because they have been flattened and therefore appear at the top level.
The results of navigating to the Sales Region page are shown in Figure 5.13.
Here you can see that the Tree and Flat views are essentially the same as their initial settings, and the Path view has now been filled. In the Path view column, note that the TreeView contains the same data as the Tree mode, but the ListBox shows only those nodes in the path between the root node and the selected node.
Flattening Nodes
Setting the FlatDepth property limits the depth of the nodes that are flattened. For example, on the left in Figure 5.14 you see a FlatDepth of 1, so only one node is flattened. On the right a FlatDepth of 2 causes three nodes to be flattenedthe top node, plus its two child nodes.
Setting the Starting Depth
The StartingDepth property indicates at which node level the data is displayed from, and it affects all three modes (Flat, Path, and Tree). For example, setting the StartingDepth to 1 (where no FlatDepth is set) is shown in Figure 5.15.
Here you can see that only nodes from level 1 down are shown and only those from our navigation pointremember, the SiteMapData Source keeps track of where we are in the navigational structure.
Setting the Starting Node Type
The StartingNodeType property identifies what type of node to start displaying data from. For example, setting this property to Parent would give the results in Figure 5.16. We've navigated to the Region node, a node that is underneath Sales. In the ListBox, for the Flat view we see only the Parent of the current node, plus its children; for the Path view, we see only the current node and its parent; and for the Tree view, we see only the parent.
Setting the StartingNodeType to Current means that only the current node is displayed, as shown in Figure 5.17. Setting the CurrentNodeType to Root means that the current node becomes the root node as far as displaying the node hierarchy is concerned.
Setting the Start Node URL
The StartingNodeUrl property allows us to set the starting point, given the URL of a page. Since URLs in the site map file must be unique, this allows us to navigate to a given node knowing only the URL, rather than its location in the hierarchy.
Showing a Navigation Path
When a site map provides the navigational architecture for a site, it's easy to add features that take advantage of this. With a hierarchy three deep or more, it has always been hard for users to remember where they are within that structure, so the idea of breadcrumbs came about, laying a trail of the path back to the root of the site.
With ASP.NET 2.0 this is simple: We have the SiteMapPath control, which automatically hooks into the site map architecture, so all you have to do is drop it on a page, as shown in Figure 5.18.
This figure shows the default implementation, just from adding the following line of code to our page:
<asp:SiteMapPath runat="server" />
To use the SiteMapPath control you don't need a SiteMapDataSource control because it works directly with the site map provider.
The current node is shown as simple text, and parent nodes are shown as hyperlinks, allowing quick navigation up the tree. The text for the tooltip is set to the description attribute from the site map file.
There are plenty of ways to customize this control to fit it to your site. The syntax is shown in Listing 5.14.
Listing 5.14. SiteMapPath Syntax
<SiteMapPath id="String" runat="server"
CurrentNodeStyle="Style"
CurrentNodeTemplate="Template"
HoverNodeStyle="Style"
NodeStyle="Style"
NodeTemplate="Template"
ParentLevelsDisplayed="Integer"
PathDirection="[CurrentToRoot|RootToCurrent]"
PathSeparator="String"
PathSeparatorStyle="Style"
PathSeparatorTemplate="Template"
RenderCurrentNodeAsLink="Boolean"
RootNodeStyle="Style"
RootNodeTemplate="Template"
ShowToolTips="Boolean"
SiteMapProvider="String"
/>
|
These are just the unique properties for this control, described in Table 5.6. All other properties are inherited and are described in the documentation.
These properties give a great deal of flexibility in how the navigation path is shown. For example, consider the code shown in Listing 5.15.
Listing 5.15. Setting the SiteMapPath Properties
<asp:SiteMapPath ID="SiteMapPath1" runat="server"
NodeStyle-Font-Name="Franklin Gothic Medium"
NodeStyle-Font-Underline="true"
NodeStyle-Font-Bold="true"
RootNodeStyle-Font-Name="Symbol"
RootNodeStyle-Font-Bold="false"
CurrentNodeStyle-Font-Name="Verdana"
CurrentNodeStyle-Font-Size="10pt"
CurrentNodeStyle-Font-Bold="true"
CurrentNodeStyle-ForeColor="red"
CurrentNodeStyle-Font-Underline="false">
<PathSeparatorTemplate>
<asp:Image runat="server" ImageUrl="arrow.gif"/>
<PathSeparatorTemplate>
</asp:SiteMapPath>
|
This defines styles for the nodes and a separator that uses a custom image. The results are shown in Figure 5.19.
Notice that the root node is underlined even though it wasn't specified as part of the RootNodeStylethe underlining was inherited from the NodeStyle.
SiteMapPath Events
The SiteMapPath is built dynamically from the data held by the underlying site map provider. As the tree of nodes is traversed, each item in the path, from the root node to the current node, is added to the Controls collection of the SiteMapPath control. Like other collection controls (such as the DataList or DataGrid), two events are fired when items are either created (ItemCreated) or bound (ItemDataBound) to the SiteMapPath. The signature for these events is the same:
Sub eventName(Sender As Object,
E As SiteMapNodeItemEventArgs)
SiteMapNodeItemEventArgs has one property, Item, which returns an object of type SiteMapNodeItem, which in turn has three properties, as described in Table 5.7.
Intercepting the ItemCreated and ItemDataBound events gives you a chance to change the default behavior as the items are created. For example, Listing 5.16 shows how you could build up an HTML meta tag consisting of the Keywords from the site map details. If the SiteMapPath control were embedded into the master page, this meta tag would be automatically constructed for each page.
Listing 5.16. SiteMapPath ItemCreated Event
<%@ Page %>
<head runat="server" id="PageHead" />
<script runat="server">
Sub ItemCreated(Sender As Object,
E As SiteMapNodeItemEventArgs)
If E.Item.ItemType = _
SiteMapNodeItemType.Current Then
Dim sb As New StringBuilder()
Dim s As String
For Each s In E.Item.SiteMapNode.Keywords
sb.Append(s)
sb.Append(" ")
Next
Dim ctl As New HtmlGenericControl("meta")
ctl.Attributes.Add("name", "keywords")
ctl.Attributes.Add("content", sb.ToString())
PageHead.Controls.Add(ctl)
End If
End Sub
</script>
<form runat="server">
<asp:SiteMapPath runat="server"
onItemCreated="ItemCreated"/>
</form>
|
The SiteMapNode Object
When the site map is constructed from the data provider, each of the items is built into a SiteMapNode object. These in turn are added to a SiteMapNodeCollection, which therefore represents all pages within a Web site. The SiteMapNode object provides links to nodes up, down, and next to it in the hierarchy and thus can be used to build a treelike structure. As shown in Listing 5.16, the ItemCreated event of the SiteMapPath object allows access to the SiteMapNode, which has the properties detailed in Table 5.8.
There are three methods for the SiteMapNode object, as described in Table 5.9.
Accessing the Site Map at Runtime
So far we've seen the site map be used by controls, but it can also be accessed directly because it is exposed through a static page property called SiteMap. For example, to access the current node within the site map, you can use the following code:
Dim currNode As SiteMapNode
currNode = SiteMap.CurrentNode
This means that even if you aren't using a SiteMapPath control, you can easily build links pointing back to the hierarchy, as shown in Listing 5.17.
Listing 5.17. Using the SiteMap Property of the Page
<script runat="server">
Sub Page_Load(Sender As Object, E As EventArgs)
ParentLink.NavigateUrl = SiteMap.CurrentNode.ParentNode.Url
End Sub
</script>
<form runat="server">
<asp:HyperLink id="ParentLink" Text="Go Back" />
</form>
|
Table 5.10 details the properties of the siteMap class.
These properties give you access to the site map details and allow you to interface into it at the programmatic level, in case more flexibility is required than the standard server controls provide.
SUMMARY
In this chapter we've looked at two very important topics: how the look and feel of sites can be implemented in ASP.NET 2.0 and how navigation around those sites can be implemented.
We've seen how a great deal of time-consuming work has been removed by the introduction of master pages, allowing the site layout and default implementation to be easily centralized. Not only does this make it easier to develop individual pages, but since layout and code can be centrally contained, it also eases maintenance and reduces potential errors.
We've also seen how ASP.NET 2.0 supplies a comprehensive architecture for site navigation. The introduction of the SiteMapDataSource and the underlying flexibility of providers allow site structure to be easily defined and used within Web pages. By placing this navigation within a master page you also have the simplicity of having to define the navigation in only a single place.
Now it's time to move on to another important topicsecurity, and how to identify users and control what they can do once they reach your site.
|
Page:
1,
2 |
|
|
|