Skip to content

Defining Sitemap Nodes using .NET Attributes

Shad Storhaug edited this page Jul 16, 2016 · 3 revisions

In the spirit of MVC, we have created a way to build convention-based nodes by specifying them as method attributes. This makes it convenient to keep the node information in the same place as your controller action. It can be accomplished by decorating your controller action methods with MvcSiteMapNodeAttribute and specifying the necessary properties. Note that every property that is available in XML is also available on MvcSiteMapNodeAttribute and each has the same purpose as if you were defining it in XML.

Note: "visibility" is a custom attribute, and must be added to the Attributes property when using MvcSiteMapNodeAttribute. For example: [MvcSiteMapNode(Title = "Some Page", Attributes = @"{ ""visibility"": ""MenuHelper,!*"" }")]. Key names are case sensitive.

Controller and Action properties are missing, as those are defined implicitly based on where you place your MvcSiteMapNodeAttribute (similar to when you use Attribute Routing in MVC).

// GET: /Checkout/Index 
[MvcSiteMapNode(Title = "Checkout", ParentKey = "Store", Key = "Checkout")] 
public ActionResult Index(int id) 
{ 
    // ... 
}

// GET: /Checkout/Complete 
[MvcSiteMapNode(Title = "Checkout complete", ParentKey = "Checkout", Key = "Checkout_Complete")] 
public ActionResult Complete(int id) 
{ 
    // ... 
}

To use this feature, ensure it is both enabled and the assembly where your nodes are located is specified in the IncludeAssembliesForScan setting in the configuration. If all of your controllers are in your MVC assembly, everything is done for you when you install the NuGet package. However, if your controllers are in a different assembly, you need to add (or change) the assembly name in the configuration.

Configuring using Internal DI

The settings are found in the web.config file (or you may add them if they are missing). The MvcSiteMapProvider_IncludeAssembliesForScan value must be a comma delimited list of .NET assembly names. Spaces are not allowed after the comma.

<appSettings> 
    <add key="MvcSiteMapProvider_IncludeAssembliesForScan" value="MyAssemblyName,MyOtherAssemblyName" />
    <add key="MvcSiteMapProvider_ScanAssembliesForSiteMapNodes" value="true" />
</appSettings>

Note: With the default configuration, you must put the home page node in the Mvc.sitemap file. You can disable XML node configuration by setting the MvcSiteMapProvider_EnableSiteMapFile web.config setting to false. Once this is done, you can safely eliminate the Mvc.sitemap and MvcSiteMapSchema.xsd files from your project.

Configuring using External DI

IncludeAssembliesForScan

This setting is a variable at the top of the MvcSiteMapProvider DI Module.

Note: The name of the module varies depending on the DI container and can be changed after installing the NuGet package, but each module is located under the \DI\<containerName>\Modules\ folder in your project by default.

string[] includeAssembliesForScan = new string[] { "MyAssemblyName", "MyOtherAssemblyName" };

Later on in the file, the variable is passed into the constructor of the ReflectionSiteMapBuilder class. This class must be registered for the MvcSiteMapNodeAttribute declarations to function. Here is an example in StructureMap:

// Register the sitemap node providers
var siteMapNodeProvider = this.For<ISiteMapNodeProvider>().Use<CompositeSiteMapNodeProvider>()
    .EnumerableOf<ISiteMapNodeProvider>().Contains(x =>
    {
        x.Type<XmlSiteMapNodeProvider>()
            .Ctor<bool>("includeRootNode").Is(true)
            .Ctor<bool>("useNestedDynamicNodeRecursion").Is(false)
            .Ctor<IXmlSource>().Is(xmlSource);
        x.Type<ReflectionSiteMapNodeProvider>()
            .Ctor<IEnumerable<string>>("includeAssemblies").Is(includeAssembliesForScan) // <-- variable passed here
            .Ctor<IEnumerable<string>>("excludeAssemblies").Is(new string[0]);
    });

Disabling XML Configuration

Similarly to internal DI, with external DI you can disable support for the Mvc.sitemap file by eliminating it from your configuration. Once this is done, you can safely eliminate the Mvc.sitemap and MvcSiteMapSchema.xsd files from your project. All examples are shown for StructureMap. Other DI configurations are similar.

Disabling the Cache Dependency

First, you need to remove the registration for RuntimeFileCacheDependency and replace it with a NullCacheDependency.

//var cacheDependency =
//    this.For<ICacheDependency>().Use<RuntimeFileCacheDependency>()
//        .Ctor<string>("fileName").Is(absoluteFileName);

var cacheDependency =
	this.For<ICacheDependency>().Use<NullCacheDependency>();
Disabling the XmlSource

Next, remove the XmlSource registration.

// Prepare for our node providers
//var xmlSource = this.For<IXmlSource>().Use<FileXmlSource>()
//               .Ctor<string>("fileName").Is(absoluteFileName);
Disabling the XmlSiteMapNodeProvider

Then, you need to remove the XmlSiteMapNodeProvider from the configuration.

// Register the sitemap node providers
var siteMapNodeProvider = this.For<ISiteMapNodeProvider>().Use<CompositeSiteMapNodeProvider>()
	.EnumerableOf<ISiteMapNodeProvider>().Contains(x =>
	{
		//x.Type<XmlSiteMapNodeProvider>()
		//    .Ctor<bool>("includeRootNode").Is(true)
		//    .Ctor<bool>("useNestedDynamicNodeRecursion").Is(false)
		//    .Ctor<IXmlSource>().Is(xmlSource);
		x.Type<ReflectionSiteMapNodeProvider>()
			.Ctor<IEnumerable<string>>("includeAssemblies").Is(includeAssembliesForScan)
			.Ctor<IEnumerable<string>>("excludeAssemblies").Is(new string[0]);
	});

Key and ParentKey

Except for the node that represents the root node, you must include the ParentKey for every node. This ParentKey must match the Key property of the node you want to use as a parent node. In most cases, you should specify Key as well as ParentKey explicitly on each MvcSiteMapNodeAttribute.

Only 1 node can be defined without a ParentKey in your configuration and that node automatically is considered to be the root node. The root node will always need to be configured in your Mvc.sitemap file unless you disable XML support as shown above.


Want to contribute? See our Contributing to MvcSiteMapProvider guide.



Version 3.x Documentation


Unofficial Documentation and Resources

Other places around the web have some documentation that is helpful for getting started and finding answers that are not found here.

Tutorials and Demos

Version 4.x
Version 3.x

Forums and Q & A Sites

Other Blog Posts

Clone this wiki locally