Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Export (0) Print
Expand All

StaticSiteMapProvider Class

Serves as a partial implementation of the abstract SiteMapProvider class and serves as a base class for the XmlSiteMapProvider class, which is the default site map provider in ASP.NET.

Namespace: System.Web
Assembly: System.Web (in system.web.dll)

'Declaration
Public MustInherit Class StaticSiteMapProvider
	Inherits SiteMapProvider
'Usage
Dim instance As StaticSiteMapProvider

public abstract class StaticSiteMapProvider extends SiteMapProvider
public abstract class StaticSiteMapProvider extends SiteMapProvider
Not applicable.

The StaticSiteMapProvider class is a partial implementation of the abstract SiteMapProvider class and supplies two additional methods: AddNode and RemoveNode, as well as the abstract BuildSiteMap and protected Clear methods.

The StaticSiteMapProvider class supports writing a site map provider (for example, an XmlSiteMapProvider) that translates a site map that is stored in persistent storage to one that is stored in memory. The StaticSiteMapProvider class provides basic implementations for storing and retrieving SiteMapNode objects.

The SiteMapProvider and StaticSiteMapProvider classes support the concept of a site map provider hierarchy, where a site map provider can have a hierarchical relationship with other site map providers. This pattern is implemented with the RootProvider and ParentProvider properties.

The StaticSiteMapProvider class stores its SiteMapNode objects in hash tables and internally uses the SiteMapNode.Url property of the pages, represented by site map nodes, as keys. (If a site map node does not specify a URL, it is tracked using an automatically generated unique key.) As a result, you cannot have site map nodes wherein a site map node with the same URL is used more than once. For example, attempting to load the site map node illustrated in the following code example with the XmlSiteMapProvider class, which is the default ASP.NET site map provider, or any site map provider that is derived from the StaticSiteMapProvider class will not work because the AboutUs.aspx page is used more than once.

<sitemap>
  <sitemapnode title="Home" description="Home" url="default.aspx" >
    <sitemapnode title="Catalog" description="Our catalog" url="catalog.aspx"/>
    <sitemapnode title="About Us" description="All about our company" url="aboutus.aspx"/>
    <sitemapnode title="Driving Directions" description="Directions to our store" url="aboutus.aspx"/>
  </sitemapnode>
</sitemap>

If you are extending the StaticSiteMapProvider class, the three most important methods are the GetRootNodeCore, Initialize, and BuildSiteMap methods. The Clear and FindSiteMapNode methods have default implementations that are sufficient for most custom site map provider implementations.

The Initialize method is called to initialize derived site map providers, including any resources that are required to load site map data, but it does attempt to build the site map node in memory. If your derived class is using files to store site map data, any file initialization can be performed here. If the site map node uses some other type of data store, such as a relational database, initializing a connection might be performed here. Additional attributes, such as file names or connection strings that are placed on the site map provider element in the configuration are processed by the ASP.NET configuration system and passed to the Initialize method with the attributes parameter.

The BuildSiteMap method must be overridden by all classes that are derived from the StaticSiteMapProvider class and is called to load the site map node from persistent storage and convert it to an internal representation. The BuildSiteMap method is called internally in many of the default member implementations of the StaticSiteMapProvider and XmlSiteMapProvider classes. If you implement your own site map provider, ensure that site map data processing occurs once and subsequent calls to the BuildSiteMap method return immediately, if site map information has already been loaded. When you implement the BuildSiteMap method, ensure it is thread safe, as multiple concurrent page requests can result indirectly in multiple calls to load site map information. The site map infrastructure supports displaying site map information based on the user's role. Depending on the Roles property that are supported by the individual SiteMapNode objects, a different navigation structure can exist for different users. The default implementations of the site map node retrieval members of the StaticSiteMapProvider class perform security trimming automatically by calling the IsAccessibleToUser method.

The AddNode, Clear and RemoveNode methods manipulate the internal collections that are used to track site map nodes in a thread-safe manner.

Notes to Inheritors: When you inherit from the StaticSiteMapProvider class, you must override the following member: BuildSiteMap.

The following code example demonstrates how you to extend the StaticSiteMapProvider class to use Microsoft Access as a site map provider. The AccessSiteMapProvider class is a site map provider that supports only a simple, one-level-deep hierarchy. The table that the site map data is stored in has the following structure:

NODEID URL            NAME       PARENTNODEID
 ---------------------------------------------
 1      default.aspx   Default    <NULL>
 2      catalog.aspx   Catalog    1
 3      aboutus.aspx   Contact Us 1
...

The AccessSiteMapProvider class is derived from the StaticSiteMapProvider class and retrieves its information from a Microsoft Access database using basic SQL queries and the OleDbCommand and OleDbDataReader objects.

Imports System
Imports System.Collections
Imports System.Collections.Specialized
Imports System.Data
Imports System.Data.OleDb
Imports System.Security.Permissions
Imports System.Web

Namespace Samples.AspNet.VB.Controls
 
    ' An extremely simple AccessSiteMapProvider that only supports a
    ' site map node hierarchy one level deep.
    <AspNetHostingPermission(SecurityAction.Demand, Level:=AspNetHostingPermissionLevel.Minimal)> _
    Public Class AccessSiteMapProvider
        Inherits StaticSiteMapProvider

        Private aRootNode As SiteMapNode = Nothing
        Private accessConnection As OleDbConnection = Nothing

        ' This string is case sensitive.
        Private AccessConnectionStringName As String = "accessSiteMapConnectionString"

        ' Implement a default constructor.
        Public Sub New()
        End Sub 'New

        ' Some basic state to help track the initialization state of the provider.
        Private initialized As Boolean = False

        Public Overridable ReadOnly Property IsInitialized() As Boolean
            Get
                Return initialized
            End Get
        End Property

        ' Return the root node of the current site map.
        Public Overrides ReadOnly Property RootNode() As SiteMapNode
            Get
                Return BuildSiteMap()
            End Get
        End Property

        Protected Overrides Function GetRootNodeCore() As SiteMapNode
            Return RootNode
        End Function

        ' Initialize is used to initialize the properties and any state that the
        ' AccessProvider holds, but is not used to build the site map.
        ' The site map is built when the BuildSiteMap method is called.
        Public Overrides Sub Initialize(ByVal name As String, ByVal attributes As NameValueCollection)
            If IsInitialized Then
                Return
            End If
            MyBase.Initialize(name, attributes)

            ' Create and test the connection to the Microsoft Access database.
            ' Retrieve the Value of the Access connection string from the
            ' attributes NameValueCollection.
            Dim connectionString As String = attributes(AccessConnectionStringName)

            If Nothing = connectionString OrElse connectionString.Length = 0 Then
                Throw New Exception("The connection string was not found.")
            Else
                accessConnection = New OleDbConnection(connectionString)
            End If
            initialized = True
        End Sub 'Initialize

        ' SiteMapProvider and StaticSiteMapProvider methods that this derived class must override.
        '
        ' Clean up any collections or other state that an instance of this may hold.
        Protected Overrides Sub Clear()
            SyncLock Me
                aRootNode = Nothing
                MyBase.Clear()
            End SyncLock
        End Sub 'Clear

        ' Build an in-memory representation from persistent
        ' storage, and return the root node of the site map.
        Public Overrides Function BuildSiteMap() As SiteMapNode

            ' Since the SiteMap class is static, make sure that it is
            ' not modified while the site map is built.
            SyncLock Me

                ' If there is no initialization, this method is being
                ' called out of order.
                If Not IsInitialized Then
                    Throw New Exception("BuildSiteMap called incorrectly.")
                End If

                ' If there is no root node, then there is no site map.
                If aRootNode Is Nothing Then
                    ' Start with a clean slate
                    Clear()

                    ' Select the root node of the site map from Microsoft Access.
                    Dim rootNodeId As Integer = -1

                    If accessConnection.State = ConnectionState.Closed Then
                        accessConnection.Open()
                    End If
                    Dim rootNodeCommand As New OleDbCommand("SELECT nodeid, url, name FROM SiteMap WHERE parentnodeid IS NULL", accessConnection)
                    Dim rootNodeReader As OleDbDataReader = rootNodeCommand.ExecuteReader()

                    If rootNodeReader.HasRows Then
                        rootNodeReader.Read()
                        rootNodeId = rootNodeReader.GetInt32(0)
                        ' Create a SiteMapNode that references the current StaticSiteMapProvider.
                        aRootNode = New SiteMapNode(Me, rootNodeId.ToString(), rootNodeReader.GetString(1), rootNodeReader.GetString(2))
                    Else
                        Return Nothing
                    End If
                    rootNodeReader.Close()
                    ' Select the child nodes of the root node.
                    Dim childNodesCommand As New OleDbCommand("SELECT nodeid, url, name FROM SiteMap WHERE parentnodeid = ?", accessConnection)
                    Dim rootParam As New OleDbParameter("parentid", OleDbType.Integer)
                    rootParam.Value = rootNodeId
                    childNodesCommand.Parameters.Add(rootParam)

                    Dim childNodesReader As OleDbDataReader = childNodesCommand.ExecuteReader()

                    If childNodesReader.HasRows Then

                        Dim childNode As SiteMapNode = Nothing
                        While childNodesReader.Read()
                            childNode = New SiteMapNode(Me, _
                            childNodesReader.GetInt32(0).ToString(), _
                            childNodesReader.GetString(1), _
                            childNodesReader.GetString(2))

                            ' Use the SiteMapNode AddNode method to add
                            ' the SiteMapNode to the ChildNodes collection.
                            AddNode(childNode, aRootNode)
                        End While
                    End If

                    childNodesReader.Close()
                    accessConnection.Close()
                End If
                Return aRootNode
            End SyncLock

        End Function 'BuildSiteMap

    End Class 'AccessSiteMapProvider

End Namespace

package Samples.AspNet.JSL;
import System.*;
import System.Collections.*;
import System.Collections.Specialized.*;
import System.Data.*;
import System.Data.OleDb.*;
import System.Web.*;
import System.Configuration.*;

/// An extremely simple AccessSiteMapProvider that only supports a
/// site map node hierarchy 1 level deep.
public class AccessSiteMapProvider extends StaticSiteMapProvider
{
	private SiteMapNode rootNode = null;
	private OleDbConnection accessConnection = null;

	// This string is case sensitive.
	public String accessConnectionStringName = "accessSiteMapConnectionString";

	// Implement a default constructor.
	public AccessSiteMapProvider()
	{
	} //AccessSiteMapProvider 

	// Some basic state to help track the initialization state of the provider.
	private boolean initialized = false;

	/** @property 
	 */
	public boolean get_IsInitialized()
	{
		return initialized;
	} //get_IsInitized.

	// Return the root node of the current site map.
	/** @property 
	 */
	public SiteMapNode get_RootNode() throws Exception
	{
		SiteMapNode temp = null;
		temp = BuildSiteMap();
		return temp;
	} //get_RootNode

	// Initialize is used to initialize the properties and any state that the
	// AccessProvider holds, but is not used to build the site map.
	// The site map is built when the BuildSiteMap method is called.
	public void Initialize(String name, NameValueCollection attributes) 
        throws Exception
	{
		if (get_IsInitialized())
		{
			return;
		}

		super.Initialize(name, attributes);
		// Create and test the connection to the Microsoft Access database.
		// Retrieve the Value of the Access connection string from the
		// attributes NameValueCollection.
		String connectionString = attributes.get_Item(
			accessConnectionStringName);

		if (null == connectionString || connectionString.get_Length() == 0)
		{
			throw new Exception("The connection string was not found.");
		}
		else
		{
			accessConnection = new OleDbConnection(connectionString);
		}
		initialized = true;
	} //Initialize

	///
	/// SiteMapProvider and StaticSiteMapProvider methods that this 
	/// derived class must override.
	///
	// Clean up any collections or other state that an instance of this may hold.
	protected void Clear()
	{
		synchronized (this)
		{
			rootNode = null;
			super.Clear();
		}
	} //Clear

	// Build an in-memory representation from persistent
	// storage, and return the root node of the site map.
	public SiteMapNode BuildSiteMap() throws Exception
	{
		// Since the SiteMap class is static, make sure that it is
		// not modified while the site map is built.
		synchronized (this)
		{
			// If there is no initialization, this method is being
			// called out of order.
			if (!get_IsInitialized())
			{
				throw new Exception("BuildSiteMap called incorrectly.");
			}
			// If there is no root node, then there is no site map.
			if (null == rootNode)
			{
				// Start with a clean slate
				Clear();
				// Select the root node of the site map from Microsoft Access.
				int rootNodeId = -1;

				if (accessConnection.get_State().Equals(ConnectionState.Closed))
				{
					accessConnection.Open();
				}

				OleDbCommand rootNodeCommand = new OleDbCommand(
					"SELECT nodeid, url, name FROM SiteMap WHERE "
					+ "parentnodeid IS NULL", accessConnection);
				OleDbDataReader rootNodeReader = rootNodeCommand.ExecuteReader();

				if (rootNodeReader.get_HasRows())
				{
					rootNodeReader.Read();
					rootNodeId = rootNodeReader.GetInt32(0);
					// Create a SiteMapNode that references the current 
					// StaticSiteMapProvider.
					rootNode = new SiteMapNode(this,
						((Int32)rootNodeId).ToString(), rootNodeReader.
						GetString(1), rootNodeReader.GetString(2));
				}
				else
				{
					return null;
				}
				rootNodeReader.Close();
				// Select the child nodes of the root node.
				OleDbCommand childNodesCommand = new OleDbCommand(
					"SELECT nodeid, url, name FROM SiteMap WHERE "
					+ "parentnodeid = ?", accessConnection);
				OleDbParameter rootParam = new OleDbParameter("parentid",
					OleDbType.Integer);
				rootParam.set_Value((Int32)rootNodeId);
				childNodesCommand.get_Parameters().Add(rootParam);

				OleDbDataReader childNodesReader = childNodesCommand.
					ExecuteReader();

				if (childNodesReader.get_HasRows())
				{
					SiteMapNode childNode = null;
					while (childNodesReader.Read())
					{
						childNode = new SiteMapNode(this,
							Convert.ToString(childNodesReader.GetInt32(0)), 
							childNodesReader.GetString(1),
							childNodesReader.GetString(2));
						// Use the SiteMapNode AddNode method to add
						// the SiteMapNode to the ChildNodes collection.
						AddNode(childNode, rootNode);
					}
				}

				childNodesReader.Close();
				accessConnection.Close();
			}
			return rootNode;
		}
	} //BuildSiteMap

	protected SiteMapNode GetRootNodeCore()
	{
		return null;
	} //GetRootNodeCore
} //AccessSiteMapProvider 

Finally, the AccessSiteMapProvider is configured as the default provider in the following Web.config file.

<configuration>
  <system.web>
    <siteMap defaultProvider="AccessSiteMapProvider">
     <providers>
       <add 
         name="AccessSiteMapProvider"
         type="Samples.AspNet.AccessSiteMapProvider,Samples.AspNet "
         accessSiteMapConnectionString="PROVIDER=MICROSOFT.JET.OLEDB.4.0;DATA SOURCE=sitemap.mdb "/>
     </providers> 
    </siteMap>
  </system.web>
</configuration>

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Windows 98, Windows Server 2000 SP4, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

The Microsoft .NET Framework 3.0 is supported on Windows Vista, Microsoft Windows XP SP2, and Windows Server 2003 SP1.

.NET Framework

Supported in: 3.0, 2.0

Community Additions

ADD
Show:
© 2015 Microsoft