diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNodeExtensions.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNodeExtensions.cs
new file mode 100644
index 00000000..7121bb9d
--- /dev/null
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNodeExtensions.cs
@@ -0,0 +1,18 @@
+using System;
+using MvcSiteMapProvider.Web.UrlResolver;
+
+namespace MvcSiteMapProvider
+{
+ ///
+ /// Contains extension logic for the ISiteMapNode interface that is not user
+ /// overridable.
+ ///
+ public static class ISiteMapNodeExtensions
+ {
+ public static bool UsesDefaultUrlResolver(this ISiteMapNode node)
+ {
+ return string.IsNullOrEmpty(node.UrlResolver) ||
+ typeof(SiteMapNodeUrlResolver).Equals(Type.GetType(node.UrlResolver, false));
+ }
+ }
+}
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Matching/SiteMapNodeUrlKey.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Matching/SiteMapNodeUrlKey.cs
index a73e25c9..646b8aa9 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Matching/SiteMapNodeUrlKey.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Matching/SiteMapNodeUrlKey.cs
@@ -23,7 +23,21 @@ IUrlPath urlPath
// Host name in absolute URL overrides this one.
this.hostName = node.HostName;
- this.SetUrlValues(node.UnresolvedUrl);
+
+ // Fixes #322 - If using a custom URL resolver, we need to account for the case that
+ // the URL will be provided by the resolver instead of specified explicitly.
+ if (!string.IsNullOrEmpty(node.UnresolvedUrl))
+ {
+ this.SetUrlValues(node.UnresolvedUrl);
+ }
+ else if (!node.UsesDefaultUrlResolver())
+ {
+ // For a custom URL resolver, if the unresolved URL property
+ // is not set use the one returned from the URL resolver.
+ // This ensures URLs that are unidentifiable by MVC can still
+ // be matched by URL.
+ this.SetUrlValues(node.Url);
+ }
}
private readonly ISiteMapNode node;
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/MvcSiteMapProvider.csproj b/src/MvcSiteMapProvider/MvcSiteMapProvider/MvcSiteMapProvider.csproj
index 0b9852b2..840e9c59 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/MvcSiteMapProvider.csproj
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/MvcSiteMapProvider.csproj
@@ -198,6 +198,7 @@
+
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMap.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMap.cs
index 3e6f6003..f3acfb32 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMap.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMap.cs
@@ -134,7 +134,7 @@ protected virtual void AddNodeInternal(ISiteMapNode node, ISiteMapNode parentNod
lock (this.synclock)
{
IUrlKey url = null;
- bool isMvcUrl = string.IsNullOrEmpty(node.UnresolvedUrl) && this.UsesDefaultUrlResolver(node);
+ bool isMvcUrl = string.IsNullOrEmpty(node.UnresolvedUrl) && node.UsesDefaultUrlResolver();
// Only store URLs if they are clickable and are configured using the Url
// property or provided by a custom URL resolver.
@@ -816,12 +816,6 @@ protected virtual ISiteMapNode ReturnNodeIfAccessible(ISiteMapNode node)
return null;
}
- protected virtual bool UsesDefaultUrlResolver(ISiteMapNode node)
- {
- return string.IsNullOrEmpty(node.UrlResolver) ||
- typeof(MvcSiteMapProvider.Web.UrlResolver.SiteMapNodeUrlResolver).Equals(Type.GetType(node.UrlResolver, false));
- }
-
protected virtual void AssertSiteMapNodeConfigurationIsValid(ISiteMapNode node)
{
ThrowIfTitleNotSet(node);