Wednesday, April 11, 2012

Inside the MvcSiteMapProvider - Part 5: The ISiteMapNodeUrlResolver

The ISiteMapNodeUrlResolver defines how URLs are resolved. The default URL resolver are fine most of the time, as it uses the different ways to resolve URLs built-in to ASP.NET MVC. But sometimes it is necessary to create a custom resolver, for example if all URL are required to be lower or upper case. In this post I’ll try to explain exactly how the default resolver works and how to implement a custom resolver.

DefaultSiteMapNodeUrlResolver

The default implementation is pretty straight forward, it preserves the parameters defined in the sitemap XML, and uses the UrlHelper from ASP.NET MVC to resolve the URLs. This can done using both a Route name and by using the action and controller name.

The first thing checked is if the node URL has been defined explicitly, which is done in either the sitemap XML or in a dynamic node provider by settings the Url property. If it has been, well, then it is returned.

Next thing done is to preserve URL parameters if this has been defined. Afterwards it is checked if the node route has been defined, again this are done in either the sitemap XML file or by settings the Route property on the MvcSiteMapNode. If it is defined the URL is resolved using the UrlHelper.RouteUrl method.

If the the route name isn’t defined, the action and controller name are used instead, and the URL is resolved using the UrlHelper.Action method.

In both cases the preserved route parameters, if any, are passed on to the URL resolver.

Custom URL resolver

To implement a custom resolver the class need to implement the ISiteMapNodeUrlResovler interface. The interface contains a single method called ResolveUrl and takes the following parameters:

mvcSiteMapNode : MvcSiteMapNode
The node which URL should be resolved.
area : string
The current node's MVC area.
controller : string
The node's controller.
action : string
The node's name.
routeValues : IDictionary<string, object>
The node's route values.

As the default implementation can be used most of the time, you class can derive from DefaultSiteMapNodeUrlResolver of easier processing. For example convert all URLs to upper case (source code taken from included sample project).

1 comment: