-
Notifications
You must be signed in to change notification settings - Fork 218
Defining Sitemap Nodes using .NET Attributes
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 usingMvcSiteMapNodeAttribute
. 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.
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 theMvcSiteMapProvider_EnableSiteMapFile
web.config setting tofalse
. Once this is done, you can safely eliminate theMvc.sitemap
andMvcSiteMapSchema.xsd
files from your project.
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]);
});
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.
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>();
Next, remove the XmlSource
registration.
// Prepare for our node providers
//var xmlSource = this.For<IXmlSource>().Use<FileXmlSource>()
// .Ctor<string>("fileName").Is(absoluteFileName);
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]);
});
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.
- Upgrading from v3 to v4
- Routing Basics
- Configuring MvcSiteMapProvider
- Defining Sitemap Nodes in XML
- Defining Sitemap Nodes using .NET Attributes
- Defining Sitemap Nodes using IDynamicNodeProvider
- HtmlHelper Extensions
- Controlling URL Behavior
- Using Action Filter Attributes
- Sitemaps XML Protocol Endpoint for Search Engines
- Using Custom Attributes on a Node
- Specifying Node Order
- Advanced Node Visibility
- Multiple Navigation Paths to a Single Page
- Multiple Sitemaps in One Application
- Security Trimming
Other places around the web have some documentation that is helpful for getting started and finding answers that are not found here.
- MvcSiteMapProvider 4.0 - A Test Drive
- MvcSiteMapProvider 4.0 - SEO Features Tutorial
- How to Make MvcSiteMapProvider Remember a User’s Position
- MvcSiteMapProvider 4.0 - Cache Configuration
- MvcSiteMapProvider 4.0 - Extending the Cache
- MvcSiteMapProvider 4.0 - Unit Testing with the SiteMaps Static Methods
- Debugging an MvcSiteMapProvider Configuration
- Converting from C# to Vb MvcSiteMapProvider
- ASP.NET MVC Menu using Site Map Provider & Bootstrap 3 Navbar
- ASP.NET MVC SiteMapPath using Site Map Provider & Bootstrap Breadcrumbs
- NightOwl888's MvcSiteMapProvider Demos - Filter for "MvcSiteMapProvider" to see the most relevant.
- MvcSiteMapProvider Tutorial and Examples
- MvcSiteMapProvider Tutorial 2 - Breadcrumbs
- Getting Started with MvcSiteMapProvider
- Inside the MvcSiteMapProvider - Part 1
- Inside the MvcSiteMapProvider - Part 2: Dynamic node providers
- Inside the MvcSiteMapProvider - Part 3: The ISiteMapVisibilityProvider
- Inside the MvcSiteMapProvider - Part 4: The IAclModule
- Inside the MvcSiteMapProvider - Part 5: The ISiteMapNodeUrlResolver
- Styling MvcSiteMapProvider with CSS
- Using MvcSiteMapProvider with Twitter Bootstrap
- ASP.NET MVC Menu using Site Map Provider & Bootstrap Navbar