diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapBuilder.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapBuilder.cs
index 528e0ada..da3940f8 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapBuilder.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapBuilder.cs
@@ -129,6 +129,7 @@ protected virtual ISiteMapNode GetSiteMapNodeFromProviderNode(ISiteMap siteMap,
siteMapNode.HttpMethod = node.GetAttributeValueOrFallback("httpMethod", "*").ToUpperInvariant();
siteMapNode.Url = node.Url;
siteMapNode.CacheResolvedUrl = bool.Parse(node.GetAttributeValueOrFallback("cacheResolvedUrl", "true"));
+ siteMapNode.IncludeAmbientRequestValues = bool.Parse(node.GetAttributeValueOrFallback("includeAmbientRequestValues", "false"));
siteMapNode.CanonicalUrl = node.GetAttributeValue("canonicalUrl");
siteMapNode.CanonicalKey = node.GetAttributeValue("canonicalKey");
siteMapNode.MetaRobotsValues.AddRange(node.GetAttributeValue("metaRobotsValues"), new[] { ' ' });
@@ -151,7 +152,7 @@ protected virtual ISiteMapNode GetSiteMapNodeFromProviderNode(ISiteMap siteMap,
}
siteMapNode.PreservedRouteParameters.AddRange(node.GetAttributeValue("preservedRouteParameters"), new[] { ',', ';' });
siteMapNode.UrlResolver = node.GetAttributeValue("urlResolver");
-
+
// Add inherited route values to sitemap node
foreach (var inheritedRouteParameter in node.GetAttributeValue("inheritedRouteParameters").Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries))
{
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapNodeProvider.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapNodeProvider.cs
index 5ece1af5..4b32fa70 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapNodeProvider.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapNodeProvider.cs
@@ -126,6 +126,7 @@ protected virtual ISiteMapNodeToParentRelation GetSiteMapNodeFromProviderNode(Sy
siteMapNode.HttpMethod = node.GetAttributeValueOrFallback("httpMethod", "*").ToUpperInvariant();
siteMapNode.Url = node.Url;
siteMapNode.CacheResolvedUrl = bool.Parse(node.GetAttributeValueOrFallback("cacheResolvedUrl", "true"));
+ siteMapNode.IncludeAmbientRequestValues = bool.Parse(node.GetAttributeValueOrFallback("includeAmbientRequestValues", "false"));
siteMapNode.CanonicalUrl = node.GetAttributeValue("canonicalUrl");
siteMapNode.CanonicalKey = node.GetAttributeValue("canonicalKey");
siteMapNode.MetaRobotsValues.AddRange(node.GetAttributeValue("metaRobotsValues"), new[] { ' ' });
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs
index b13a8152..cb9b2ab5 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs
@@ -451,6 +451,7 @@ protected virtual ISiteMapNode GetSiteMapNodeFromMvcSiteMapNodeAttribute(ISiteMa
siteMapNode.HttpMethod = httpMethod;
if (!string.IsNullOrEmpty(attribute.Url)) siteMapNode.Url = attribute.Url;
siteMapNode.CacheResolvedUrl = attribute.CacheResolvedUrl;
+ siteMapNode.IncludeAmbientRequestValues = attribute.IncludeAmbientRequestValues;
siteMapNode.CanonicalUrl = attribute.CanonicalUrl;
siteMapNode.CanonicalKey = attribute.CanonicalKey;
siteMapNode.MetaRobotsValues.AddRange(attribute.MetaRobotsValues);
@@ -464,7 +465,7 @@ protected virtual ISiteMapNode GetSiteMapNodeFromMvcSiteMapNodeAttribute(ISiteMa
siteMapNode.RouteValues.AddRange(attribute.Attributes, false);
siteMapNode.PreservedRouteParameters.AddRange(attribute.PreservedRouteParameters, new[] { ',', ';' });
siteMapNode.UrlResolver = attribute.UrlResolver;
-
+
// Specified area, controller and action properties will override any
// provided in the attributes collection.
if (!string.IsNullOrEmpty(area)) siteMapNode.RouteValues.Add("area", area);
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapNodeProvider.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapNodeProvider.cs
index d7f1a4af..571a429d 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapNodeProvider.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapNodeProvider.cs
@@ -248,6 +248,7 @@ protected virtual ISiteMapNodeToParentRelation GetSiteMapNodeFromMvcSiteMapNodeA
node.HttpMethod = httpMethod;
if (!string.IsNullOrEmpty(attribute.Url)) node.Url = attribute.Url;
node.CacheResolvedUrl = attribute.CacheResolvedUrl;
+ node.IncludeAmbientRequestValues = attribute.IncludeAmbientRequestValues;
node.CanonicalUrl = attribute.CanonicalUrl;
node.CanonicalKey = attribute.CanonicalKey;
node.MetaRobotsValues.AddRange(attribute.MetaRobotsValues);
@@ -261,7 +262,7 @@ protected virtual ISiteMapNodeToParentRelation GetSiteMapNodeFromMvcSiteMapNodeA
node.RouteValues.AddRange(attribute.Attributes, false);
node.PreservedRouteParameters.AddRange(attribute.PreservedRouteParameters, new[] { ',', ';' });
node.UrlResolver = attribute.UrlResolver;
-
+
// Specified area, controller and action properties will override any
// provided in the attributes collection.
if (!string.IsNullOrEmpty(area)) node.RouteValues.Add("area", area);
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReservedAttributeNameProvider.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReservedAttributeNameProvider.cs
index 05b7bb8b..9b2ae728 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReservedAttributeNameProvider.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReservedAttributeNameProvider.cs
@@ -67,6 +67,7 @@ protected virtual bool IsKnownAttribute(string attributeName)
|| attributeName == "imageUrl"
|| attributeName == "inheritedRouteParameters"
|| attributeName == "preservedRouteParameters"
+ || attributeName == "includeAmbientRequestValues"
|| attributeName == "canonicalUrl"
|| attributeName == "canonicalKey"
|| attributeName == "metaRobotsValues";
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapBuilder.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapBuilder.cs
index a8fe9343..3faecadc 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapBuilder.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapBuilder.cs
@@ -154,6 +154,7 @@ protected virtual ISiteMapNode GetSiteMapNodeFromXmlElement(ISiteMap siteMap, XE
siteMapNode.HttpMethod = httpMethod;
siteMapNode.Url = url;
siteMapNode.CacheResolvedUrl = bool.Parse(node.GetAttributeValueOrFallback("cacheResolvedUrl", "true"));
+ siteMapNode.IncludeAmbientRequestValues = bool.Parse(node.GetAttributeValueOrFallback("includeAmbientRequestValues", "false"));
siteMapNode.CanonicalUrl = node.GetAttributeValue("canonicalUrl");
siteMapNode.CanonicalKey = node.GetAttributeValue("canonicalKey");
siteMapNode.MetaRobotsValues.AddRange(node.GetAttributeValue("metaRobotsValues"), new[] { ' ' });
@@ -169,7 +170,7 @@ protected virtual ISiteMapNode GetSiteMapNodeFromXmlElement(ISiteMap siteMap, XE
siteMapNode.RouteValues.AddRange(node, false);
siteMapNode.PreservedRouteParameters.AddRange(node.GetAttributeValue("preservedRouteParameters"), new[] { ',', ';' });
siteMapNode.UrlResolver = node.GetAttributeValue("urlResolver");
-
+
// Area and controller may need inheriting from the parent node, so set (or reset) them explicitly
siteMapNode.Area = area;
siteMapNode.Controller = controller;
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapNodeProvider.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapNodeProvider.cs
index fe625f84..53484ae4 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapNodeProvider.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapNodeProvider.cs
@@ -229,6 +229,7 @@ protected virtual ISiteMapNodeToParentRelation GetSiteMapNodeFromXmlElement(XEle
siteMapNode.HttpMethod = httpMethod;
siteMapNode.Url = url;
siteMapNode.CacheResolvedUrl = bool.Parse(node.GetAttributeValueOrFallback("cacheResolvedUrl", "true"));
+ siteMapNode.IncludeAmbientRequestValues = bool.Parse(node.GetAttributeValueOrFallback("includeAmbientRequestValues", "false"));
siteMapNode.CanonicalUrl = node.GetAttributeValue("canonicalUrl");
siteMapNode.CanonicalKey = node.GetAttributeValue("canonicalKey");
siteMapNode.MetaRobotsValues.AddRange(node.GetAttributeValue("metaRobotsValues"), new[] { ' ' });
@@ -242,7 +243,7 @@ protected virtual ISiteMapNodeToParentRelation GetSiteMapNodeFromXmlElement(XEle
siteMapNode.RouteValues.AddRange(node, false);
siteMapNode.PreservedRouteParameters.AddRange(node.GetAttributeValue("preservedRouteParameters"), new[] { ',', ';' });
siteMapNode.UrlResolver = node.GetAttributeValue("urlResolver");
-
+
// Area and controller may need inheriting from the parent node, so set (or reset) them explicitly
siteMapNode.Area = area;
siteMapNode.Controller = controller;
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/DynamicNode.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/DynamicNode.cs
index d572775b..2c9dac90 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/DynamicNode.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/DynamicNode.cs
@@ -191,6 +191,13 @@ public virtual UpdatePriority UpdatePriority
///
public virtual bool? Clickable { get; set; }
+ ///
+ /// Gets or sets a value indicating whether to include ambient request values
+ /// (from the RouteValues and/or query string) when resolving URLs.
+ ///
+ /// true to include ambient values (like MVC does); otherwise false.
+ public virtual bool? IncludeAmbientRequestValues { get; set; }
+
///
/// Copies the values for matching properties on an instance, but
/// doesn't overwrite any values that are not set in this instance.
@@ -276,6 +283,8 @@ public virtual void SafeCopyTo(ISiteMapNode node)
node.UrlResolver = this.UrlResolver;
if (this.Clickable != null)
node.Clickable = (bool)this.Clickable;
+ if (this.IncludeAmbientRequestValues != null)
+ node.IncludeAmbientRequestValues = (bool)this.IncludeAmbientRequestValues;
}
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/IMvcSiteMapNodeAttribute.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/IMvcSiteMapNodeAttribute.cs
index 7dbb1ed1..bec5d984 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/IMvcSiteMapNodeAttribute.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/IMvcSiteMapNodeAttribute.cs
@@ -152,6 +152,13 @@ public interface IMvcSiteMapNodeAttribute
///
string PreservedRouteParameters { get; set; }
+ ///
+ /// Gets or sets a value indicating whether to include ambient request values
+ /// (from the RouteValues and/or query string) when resolving URLs.
+ ///
+ /// true to include ambient values (like MVC does); otherwise false.
+ bool IncludeAmbientRequestValues { get; set; }
+
///
/// Gets or sets the attributes (optional).
///
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs
index 685f0f9d..a27bdcff 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs
@@ -59,6 +59,7 @@ public interface ISiteMapNode
string ResolvedUrl { get; }
bool CacheResolvedUrl { get; set; }
void ResolveUrl();
+ bool IncludeAmbientRequestValues { get; set; }
bool HasAbsoluteUrl();
bool HasExternalUrl(HttpContextBase httpContext);
@@ -74,7 +75,7 @@ public interface ISiteMapNode
IPreservedRouteParameterCollection PreservedRouteParameters { get; }
RouteData GetRouteData(HttpContextBase httpContext);
bool MatchesRoute(IDictionary routeValues);
-
+
string Area { get; set; }
string Controller { get; set; }
string Action { get; set; }
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/LockableSiteMapNode.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/LockableSiteMapNode.cs
index 3cebe9f1..c5aaca06 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/LockableSiteMapNode.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/LockableSiteMapNode.cs
@@ -269,6 +269,20 @@ public override bool CacheResolvedUrl
}
}
+ ///
+ /// Gets or sets a value indicating whether to include ambient request values
+ /// (from the RouteValues and/or query string) when resolving URLs.
+ ///
+ /// true to include ambient values (like MVC does); otherwise false.
+ public override bool IncludeAmbientRequestValues
+ {
+ get { return base.IncludeAmbientRequestValues; }
+ set
+ {
+ this.ThrowIfReadOnly("IncludeAmbientRequestValues");
+ base.IncludeAmbientRequestValues = value;
+ }
+ }
///
/// Sets the ResolvedUrl using the current Url or Url resolver.
@@ -279,7 +293,6 @@ public override void ResolveUrl()
base.ResolveUrl();
}
-
#endregion
#region Canonical Tag
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/MvcSiteMapNodeAttribute.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/MvcSiteMapNodeAttribute.cs
index 7e04900b..93faa029 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/MvcSiteMapNodeAttribute.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/MvcSiteMapNodeAttribute.cs
@@ -15,6 +15,7 @@ public class MvcSiteMapNodeAttribute : Attribute, IMvcSiteMapNodeAttribute
public MvcSiteMapNodeAttribute()
{
Clickable = true;
+ IncludeAmbientRequestValues = false;
}
///
@@ -163,6 +164,13 @@ public MvcSiteMapNodeAttribute()
///
public string PreservedRouteParameters { get; set; }
+ ///
+ /// Gets or sets a value indicating whether to include ambient request values
+ /// (from the RouteValues and/or query string) when resolving URLs.
+ ///
+ /// true to include ambient values (like MVC does); otherwise false.
+ public bool IncludeAmbientRequestValues { get; set; }
+
///
/// Gets or sets the attributes (optional).
///
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNode.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNode.cs
index c5f16eba..7e195816 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNode.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNode.cs
@@ -375,7 +375,7 @@ public override string Url
public override void ResolveUrl()
{
if (this.CacheResolvedUrl && string.IsNullOrEmpty(this.UnresolvedUrl) &&
- this.preservedRouteParameters.Count == 0 && !this.RouteValues.ContainsCustomKeys)
+ this.preservedRouteParameters.Count == 0 && !this.IncludeAmbientRequestValues)
{
this.resolvedUrl = this.GetResolvedUrl();
}
@@ -389,6 +389,13 @@ protected string GetResolvedUrl()
this.UrlResolver, this, this.Area, this.Controller, this.Action, this.RouteValues);
}
+ ///
+ /// Gets or sets a value indicating whether to include ambient request values
+ /// (from the RouteValues and/or query string) when resolving URLs.
+ ///
+ /// true to include ambient values (like MVC does); otherwise false.
+ public override bool IncludeAmbientRequestValues { get; set; }
+
///
/// Gets a boolean value that indicates this is an external URL by checking whether it
/// looks like an absolute path.
@@ -723,6 +730,7 @@ public override void CopyTo(ISiteMapNode node)
node.Route = this.Route;
this.RouteValues.CopyTo(node.RouteValues);
this.PreservedRouteParameters.CopyTo(node.PreservedRouteParameters);
+ node.IncludeAmbientRequestValues = this.IncludeAmbientRequestValues;
// NOTE: Area, Controller, and Action are covered under RouteValues.
}
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs
index 675d2b4b..d7e9981f 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs
@@ -69,6 +69,7 @@ public virtual bool IsAccessibleToUser()
public abstract string ResolvedUrl { get; }
public abstract bool CacheResolvedUrl { get; set; }
public abstract void ResolveUrl();
+ public abstract bool IncludeAmbientRequestValues { get; set; }
public abstract bool HasAbsoluteUrl();
public abstract bool HasExternalUrl(HttpContextBase httpContext);
public abstract string CanonicalUrl { get; set; }
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Web/UrlResolver/SiteMapNodeUrlResolver.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Web/UrlResolver/SiteMapNodeUrlResolver.cs
index 4f5461e8..8d58d798 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Web/UrlResolver/SiteMapNodeUrlResolver.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Web/UrlResolver/SiteMapNodeUrlResolver.cs
@@ -69,7 +69,7 @@ protected virtual string ResolveRouteUrl(ISiteMapNode node, string area, string
// which doesn't consume resources
using (var nullWriter = new StreamWriter(Stream.Null))
{
- var requestContext = this.CreateRequestContext(node, true, nullWriter);
+ var requestContext = this.CreateRequestContext(node, nullWriter);
result = this.ResolveRouteUrl(node, area, controller, action, routeValues, requestContext);
}
@@ -110,9 +110,9 @@ protected virtual HttpContextBase CreateHttpContext(ISiteMapNode node, TextWrite
return this.mvcContextFactory.CreateHttpContext(node, uri, writer);
}
- protected virtual RequestContext CreateRequestContext(ISiteMapNode node, bool includeAmbientRequestValues, TextWriter writer)
+ protected virtual RequestContext CreateRequestContext(ISiteMapNode node, TextWriter writer)
{
- if (!includeAmbientRequestValues)
+ if (!node.IncludeAmbientRequestValues)
{
var httpContext = this.CreateHttpContext(node, writer);
return this.mvcContextFactory.CreateRequestContext(httpContext);
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Xml/MvcSiteMapSchema.xsd b/src/MvcSiteMapProvider/MvcSiteMapProvider/Xml/MvcSiteMapSchema.xsd
index 2a291612..591e0744 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Xml/MvcSiteMapSchema.xsd
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Xml/MvcSiteMapSchema.xsd
@@ -137,6 +137,14 @@
+
+
+
+ Optional. Whether or not to include request route values and/or query string values when resolving the
+ URL (for route/action URLs only). Default is false.
+
+
+
@@ -144,7 +152,6 @@
-
@@ -159,7 +166,6 @@
-
@@ -167,7 +173,6 @@
-
@@ -175,7 +180,6 @@
-
@@ -191,7 +195,6 @@
-
@@ -199,7 +202,6 @@
-
@@ -207,7 +209,6 @@
-