Skip to content

Commit

Permalink
Fixes #213, added IncludeAmbientRequestValues as a feature of ISiteMa…
Browse files Browse the repository at this point in the history
…pNode and provided support for populating this property through XML, Dynamic Nodes, and MvcSiteMapNodeAttribute.
  • Loading branch information
NightOwl888 committed Mar 3, 2014
1 parent 47008d0 commit 705cf3a
Show file tree
Hide file tree
Showing 16 changed files with 73 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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[] { ' ' });
Expand All @@ -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))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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[] { ' ' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ protected virtual bool IsKnownAttribute(string attributeName)
|| attributeName == "imageUrl"
|| attributeName == "inheritedRouteParameters"
|| attributeName == "preservedRouteParameters"
|| attributeName == "includeAmbientRequestValues"
|| attributeName == "canonicalUrl"
|| attributeName == "canonicalKey"
|| attributeName == "metaRobotsValues";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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[] { ' ' });
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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[] { ' ' });
Expand All @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions src/MvcSiteMapProvider/MvcSiteMapProvider/DynamicNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ public virtual UpdatePriority UpdatePriority
/// </value>
public virtual bool? Clickable { get; set; }

/// <summary>
/// Gets or sets a value indicating whether to include ambient request values
/// (from the RouteValues and/or query string) when resolving URLs.
/// </summary>
/// <value><b>true</b> to include ambient values (like MVC does); otherwise <b>false</b>.</value>
public virtual bool? IncludeAmbientRequestValues { get; set; }

/// <summary>
/// Copies the values for matching properties on an <see cref="T:MvcSiteMapNodeProvider.ISiteMapNode"/> instance, but
/// doesn't overwrite any values that are not set in this <see cref="T:MvcSiteMapNodeProvider.DynamicNode"/> instance.
Expand Down Expand Up @@ -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;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ public interface IMvcSiteMapNodeAttribute
/// </value>
string PreservedRouteParameters { get; set; }

/// <summary>
/// Gets or sets a value indicating whether to include ambient request values
/// (from the RouteValues and/or query string) when resolving URLs.
/// </summary>
/// <value><b>true</b> to include ambient values (like MVC does); otherwise <b>false</b>.</value>
bool IncludeAmbientRequestValues { get; set; }

/// <summary>
/// Gets or sets the attributes (optional).
///
Expand Down
3 changes: 2 additions & 1 deletion src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -74,7 +75,7 @@ public interface ISiteMapNode
IPreservedRouteParameterCollection PreservedRouteParameters { get; }
RouteData GetRouteData(HttpContextBase httpContext);
bool MatchesRoute(IDictionary<string, object> routeValues);

string Area { get; set; }
string Controller { get; set; }
string Action { get; set; }
Expand Down
15 changes: 14 additions & 1 deletion src/MvcSiteMapProvider/MvcSiteMapProvider/LockableSiteMapNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,20 @@ public override bool CacheResolvedUrl
}
}

/// <summary>
/// Gets or sets a value indicating whether to include ambient request values
/// (from the RouteValues and/or query string) when resolving URLs.
/// </summary>
/// <value><b>true</b> to include ambient values (like MVC does); otherwise <b>false</b>.</value>
public override bool IncludeAmbientRequestValues
{
get { return base.IncludeAmbientRequestValues; }
set
{
this.ThrowIfReadOnly("IncludeAmbientRequestValues");
base.IncludeAmbientRequestValues = value;
}
}

/// <summary>
/// Sets the ResolvedUrl using the current Url or Url resolver.
Expand All @@ -279,7 +293,6 @@ public override void ResolveUrl()
base.ResolveUrl();
}


#endregion

#region Canonical Tag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class MvcSiteMapNodeAttribute : Attribute, IMvcSiteMapNodeAttribute
public MvcSiteMapNodeAttribute()
{
Clickable = true;
IncludeAmbientRequestValues = false;
}

/// <summary>
Expand Down Expand Up @@ -163,6 +164,13 @@ public MvcSiteMapNodeAttribute()
/// </value>
public string PreservedRouteParameters { get; set; }

/// <summary>
/// Gets or sets a value indicating whether to include ambient request values
/// (from the RouteValues and/or query string) when resolving URLs.
/// </summary>
/// <value><b>true</b> to include ambient values (like MVC does); otherwise <b>false</b>.</value>
public bool IncludeAmbientRequestValues { get; set; }

/// <summary>
/// Gets or sets the attributes (optional).
///
Expand Down
10 changes: 9 additions & 1 deletion src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -389,6 +389,13 @@ protected string GetResolvedUrl()
this.UrlResolver, this, this.Area, this.Controller, this.Action, this.RouteValues);
}

/// <summary>
/// Gets or sets a value indicating whether to include ambient request values
/// (from the RouteValues and/or query string) when resolving URLs.
/// </summary>
/// <value><b>true</b> to include ambient values (like MVC does); otherwise <b>false</b>.</value>
public override bool IncludeAmbientRequestValues { get; set; }

/// <summary>
/// Gets a boolean value that indicates this is an external URL by checking whether it
/// looks like an absolute path.
Expand Down Expand Up @@ -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.
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,21 @@
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="includeAmbientRequestValues" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>
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.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="visibility" type="xs:string" use="optional" >
<xs:annotation>
<xs:documentation>
Example from demo: visibility="SiteMapPathHelper,!*"
</xs:documentation>
</xs:annotation>
</xs:attribute>

<xs:attribute name="visibilityProvider" type="xs:string" use="optional" >
<xs:annotation>
<xs:documentation>
Expand All @@ -159,23 +166,20 @@
</xs:documentation>
</xs:annotation>
</xs:attribute>

<xs:attribute name="imageUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>
Optional image to be shown by supported HtmlHelpers.
</xs:documentation>
</xs:annotation>
</xs:attribute>

<xs:attribute name="preservedRouteParameters" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>
Optional preserved route parameter names (= values that will be used from the current request route).
</xs:documentation>
</xs:annotation>
</xs:attribute>

<xs:attribute name="canonicalUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>
Expand All @@ -191,23 +195,20 @@
</xs:documentation>
</xs:annotation>
</xs:attribute>

<xs:attribute name="metaRobotsValues" type="metarobots_type" use="optional">
<xs:annotation>
<xs:documentation>
Optional. A space-delimited list of values to apply to the robots meta tag. These will apply to all robots.
</xs:documentation>
</xs:annotation>
</xs:attribute>

<xs:attribute name="httpMethod" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>
The HTTP method that will be used to check node accessibility. This value is used to select correct controller action if a controller has multiple action accepting different HTTP verbs. Set to * to use HTTP method of current request.
</xs:documentation>
</xs:annotation>
</xs:attribute>

<xs:attribute name="order" type="xs:int" use="optional">
<xs:annotation>
<xs:documentation>
Expand Down

0 comments on commit 705cf3a

Please sign in to comment.