diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapBuilder.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapBuilder.cs
index 528e0ada..2ecc3b47 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapBuilder.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapBuilder.cs
@@ -151,6 +151,7 @@ protected virtual ISiteMapNode GetSiteMapNodeFromProviderNode(ISiteMap siteMap,
}
siteMapNode.PreservedRouteParameters.AddRange(node.GetAttributeValue("preservedRouteParameters"), new[] { ',', ';' });
siteMapNode.UrlResolver = node.GetAttributeValue("urlResolver");
+ siteMapNode.IncludeAmbientRequestValues = bool.Parse(node.GetAttributeValueOrFallback("includeAmbientRequestValues", "false"));
// 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..cb59f1ca 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapNodeProvider.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/AspNetSiteMapNodeProvider.cs
@@ -148,6 +148,7 @@ protected virtual ISiteMapNodeToParentRelation GetSiteMapNodeFromProviderNode(Sy
}
siteMapNode.PreservedRouteParameters.AddRange(node.GetAttributeValue("preservedRouteParameters"), new[] { ',', ';' });
siteMapNode.UrlResolver = node.GetAttributeValue("urlResolver");
+ siteMapNode.IncludeAmbientRequestValues = bool.Parse(node.GetAttributeValueOrFallback("includeAmbientRequestValues", "false"));
// 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/ReflectionSiteMapBuilder.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs
index b13a8152..8e68d7ac 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs
@@ -464,6 +464,7 @@ protected virtual ISiteMapNode GetSiteMapNodeFromMvcSiteMapNodeAttribute(ISiteMa
siteMapNode.RouteValues.AddRange(attribute.Attributes, false);
siteMapNode.PreservedRouteParameters.AddRange(attribute.PreservedRouteParameters, new[] { ',', ';' });
siteMapNode.UrlResolver = attribute.UrlResolver;
+ siteMapNode.IncludeAmbientRequestValues = attribute.IncludeAmbientRequestValues;
// Specified area, controller and action properties will override any
// provided in the attributes collection.
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapNodeProvider.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapNodeProvider.cs
index 0c8742a4..5d47fcf3 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapNodeProvider.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapNodeProvider.cs
@@ -261,6 +261,7 @@ protected virtual ISiteMapNodeToParentRelation GetSiteMapNodeFromMvcSiteMapNodeA
node.RouteValues.AddRange(attribute.Attributes, false);
node.PreservedRouteParameters.AddRange(attribute.PreservedRouteParameters, new[] { ',', ';' });
node.UrlResolver = attribute.UrlResolver;
+ node.IncludeAmbientRequestValues = attribute.IncludeAmbientRequestValues;
// Specified area, controller and action properties will override any
// provided in the attributes collection.
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..bd6fec1a 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapBuilder.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapBuilder.cs
@@ -169,6 +169,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");
+ siteMapNode.IncludeAmbientRequestValues = bool.Parse(node.GetAttributeValueOrFallback("includeAmbientRequestValues", "false"));
// Area and controller may need inheriting from the parent node, so set (or reset) them explicitly
siteMapNode.Area = area;
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapNodeProvider.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapNodeProvider.cs
index c5c028cd..dda5e9f5 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapNodeProvider.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/XmlSiteMapNodeProvider.cs
@@ -242,6 +242,7 @@ protected virtual ISiteMapNodeToParentRelation GetSiteMapNodeFromXmlElement(XEle
siteMapNode.RouteValues.AddRange(node, false);
siteMapNode.PreservedRouteParameters.AddRange(node.GetAttributeValue("preservedRouteParameters"), new[] { ',', ';' });
siteMapNode.UrlResolver = node.GetAttributeValue("urlResolver");
+ siteMapNode.IncludeAmbientRequestValues = bool.Parse(node.GetAttributeValueOrFallback("includeAmbientRequestValues", "false"));
// Area and controller may need inheriting from the parent node, so set (or reset) them explicitly
siteMapNode.Area = area;
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..94ada548 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs
@@ -74,6 +74,7 @@ public interface ISiteMapNode
IPreservedRouteParameterCollection PreservedRouteParameters { get; }
RouteData GetRouteData(HttpContextBase httpContext);
bool MatchesRoute(IDictionary routeValues);
+ bool IncludeAmbientRequestValues { get; set; }
string Area { get; set; }
string Controller { get; set; }
diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/LockableSiteMapNode.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/LockableSiteMapNode.cs
index 3cebe9f1..eb6bb443 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/LockableSiteMapNode.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/LockableSiteMapNode.cs
@@ -331,6 +331,21 @@ public override string Route
}
}
+ ///
+ /// 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;
+ }
+ }
+
#endregion
#region MVC
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..e23ab027 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();
}
@@ -657,6 +657,13 @@ public override bool MatchesRoute(IDictionary routeValues)
return this.RouteValues.MatchesRoute(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; }
+
#endregion
#region MVC
@@ -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..c203ba9a 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs
@@ -81,6 +81,7 @@ public virtual bool IsAccessibleToUser()
public abstract IPreservedRouteParameterCollection PreservedRouteParameters { get; }
public abstract RouteData GetRouteData(HttpContextBase httpContext);
public abstract bool MatchesRoute(IDictionary routeValues);
+ public abstract bool IncludeAmbientRequestValues { get; set; }
public abstract string Area { get; set; }
public abstract string Controller { get; set; }
public abstract string Action { 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..7be3a5aa 100644
--- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Xml/MvcSiteMapSchema.xsd
+++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Xml/MvcSiteMapSchema.xsd
@@ -176,6 +176,15 @@
+
+
+
+ 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.
+
+
+
+