/// <summary> /// Creates a new node that is a copy of the current node with a specified key. /// </summary> /// <param name="key">The key.</param> /// <returns> /// A new node that is a copy of the current node. /// </returns> public virtual SiteMapNode Clone(string key) { MvcSiteMapNode clone = new MvcSiteMapNode(Provider, key, new NameValueCollection(), null); if (RouteValues != null) { clone.RouteValues = new Dictionary <string, object>(RouteValues); } if (Attributes != null) { clone.Attributes = new NameValueCollection(Attributes); } if (Roles != null) { clone.Roles = new ArrayList(Roles); } clone.Title = Title; clone.Description = Description; clone.Clickable = Clickable; clone.LastModifiedDate = LastModifiedDate; clone.ChangeFrequency = ChangeFrequency; clone.UpdatePriority = UpdatePriority; clone.TargetFrame = TargetFrame; clone.ImageUrl = ImageUrl; clone.PreservedRouteParameters = PreservedRouteParameters; clone.InheritedRouteParameters = InheritedRouteParameters; return(clone); }
/// <summary> /// Resolves the URL. /// </summary> /// <param name="mvcSiteMapNode">The MVC site map node.</param> /// <param name="area">The area.</param> /// <param name="controller">The controller.</param> /// <param name="action">The action.</param> /// <param name="routeValues">The route values.</param> /// <returns>The resolved URL.</returns> public virtual string ResolveUrl(MvcSiteMapNode mvcSiteMapNode, string area, string controller, string action, IDictionary<string, object> routeValues) { if (mvcSiteMapNode["url"] != null) { if (mvcSiteMapNode["url"].StartsWith("~")) { return System.Web.VirtualPathUtility.ToAbsolute(mvcSiteMapNode["url"]); } else { return mvcSiteMapNode["url"]; } } if (!string.IsNullOrEmpty(mvcSiteMapNode.PreservedRouteParameters)) { foreach (var item in mvcSiteMapNode.PreservedRouteParameters.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)) { var preservedParameterName = item.Trim(); if (!string.IsNullOrEmpty(preservedParameterName)) { routeValues[preservedParameterName] = UrlHelper.RequestContext.RouteData.Values[preservedParameterName]; } } } //cache already generated routes. //I don't know why the result of Url was not saved to this["url"], perhaps because //theoretically it is possible to change RouteValues dynamically. So I decided to //store last version var key = mvcSiteMapNode.Route ?? string.Empty; foreach (var routeValue in routeValues) key += routeValue.Key + (routeValue.Value ?? string.Empty); if (_urlkey == key) return _url; string returnValue = null; if (!string.IsNullOrEmpty(mvcSiteMapNode.Route)) { returnValue = UrlHelper.RouteUrl(mvcSiteMapNode.Route, new RouteValueDictionary(routeValues)); } else { returnValue = UrlHelper.Action(action, controller, new RouteValueDictionary(routeValues)); } if (string.IsNullOrEmpty(returnValue)) { throw new UrlResolverException(string.Format(Messages.CouldNotResolve, mvcSiteMapNode.Title, action, controller, mvcSiteMapNode.Route ?? "")); } _urlkey = key; _url = returnValue; return returnValue; }
/// <summary> /// Resolves the URL. /// </summary> /// <param name="mvcSiteMapNode">The MVC site map node.</param> /// <param name="area">The area.</param> /// <param name="controller">The controller.</param> /// <param name="action">The action.</param> /// <param name="routeValues">The route values.</param> /// <returns>The resolved URL.</returns> public virtual string ResolveUrl(MvcSiteMapNode mvcSiteMapNode, string area, string controller, string action, IDictionary <string, object> routeValues) { if (mvcSiteMapNode["url"] != null) { if (mvcSiteMapNode["url"].StartsWith("~")) { return(System.Web.VirtualPathUtility.ToAbsolute(mvcSiteMapNode["url"])); } else { return(mvcSiteMapNode["url"]); } } if (!string.IsNullOrEmpty(mvcSiteMapNode.PreservedRouteParameters)) { foreach (var item in mvcSiteMapNode.PreservedRouteParameters.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)) { var preservedParameterName = item.Trim(); routeValues[preservedParameterName] = UrlHelper.RequestContext.RouteData.Values[preservedParameterName]; } } string returnValue = null; if (!string.IsNullOrEmpty(mvcSiteMapNode.Route)) { returnValue = UrlHelper.RouteUrl(mvcSiteMapNode.Route, new RouteValueDictionary(routeValues)); } else { returnValue = UrlHelper.Action(action, controller, new RouteValueDictionary(routeValues)); } if (string.IsNullOrEmpty(returnValue)) { throw new UrlResolverException(string.Format(Messages.CouldNotResolve, mvcSiteMapNode.Title, action, controller, mvcSiteMapNode.Route ?? "")); } return(returnValue); }
/// <summary> /// Creates a new node that is a copy of the current node with a specified key. /// </summary> /// <param name="key">The key.</param> /// <returns> /// A new node that is a copy of the current node. /// </returns> public virtual SiteMapNode Clone(string key) { MvcSiteMapNode clone = new MvcSiteMapNode(Provider, key, new NameValueCollection(), null); if (RouteValues != null) { clone.RouteValues = new Dictionary<string, object>(RouteValues); } if (Attributes != null) { clone.Attributes = new NameValueCollection(Attributes); } if (Roles != null) { clone.Roles = new ArrayList(Roles); } clone.Title = Title; clone.Description = Description; clone.Clickable = Clickable; clone.LastModifiedDate = LastModifiedDate; clone.ChangeFrequency = ChangeFrequency; clone.UpdatePriority = UpdatePriority; clone.TargetFrame = TargetFrame; clone.ImageUrl = ImageUrl; clone.PreservedRouteParameters = PreservedRouteParameters; clone.InheritedRouteParameters = InheritedRouteParameters; return clone; }
/// <summary> /// Add each attribute to our attributes collection on the siteMapNode /// and to a route data dictionary. /// </summary> /// <param name="node">The element to map.</param> /// <param name="siteMapNode">The SiteMapNode to map to</param> /// <param name="routeValues">The RouteValueDictionary to fill</param> protected virtual void AttributesToRouteValues(XElement node, MvcSiteMapNode siteMapNode, IDictionary<string, object> routeValues) { foreach (XAttribute attribute in node.Attributes()) { var attributeName = attribute.Name.ToString(); var attributeValue = attribute.Value; if (attributeName != "title" && attributeName != "description") { siteMapNode[attributeName] = attributeValue; } // Process route values if ( attributeName != "title" && attributeName != "description" && attributeName != "resourceKey" && attributeName != "key" && attributeName != "roles" && attributeName != "url" && attributeName != "clickable" && attributeName != "dynamicNodeProvider" && attributeName != "urlResolver" && attributeName != "visibilityProvider" && attributeName != "lastModifiedDate" && attributeName != "changeFrequency" && attributeName != "updatePriority" && attributeName != "targetFrame" && attributeName != "imageUrl" && attributeName != "inheritedRouteParameters" && attributeName != "preservedRouteParameters" && !attributesToIgnore.Contains(attributeName) && !attributeName.StartsWith("data-") ) { routeValues.Add(attributeName, attributeValue); } if (attributeName == "roles") { siteMapNode.Roles = attribute.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); } } }
/// <summary> /// Nodes the matches route. /// </summary> /// <param name="mvcNode">The MVC node.</param> /// <param name="values">The values.</param> /// <returns> /// A matches route represented as a <see cref="bool"/> instance /// </returns> private bool NodeMatchesRoute(MvcSiteMapNode mvcNode, IDictionary<string, object> values) { var nodeValid = true; if (mvcNode != null) { // Find action method parameters? IEnumerable<string> actionParameters = new List<string>(); if (mvcNode.DynamicNodeProvider == null && mvcNode.IsDynamic == false) { actionParameters = ActionMethodParameterResolver.ResolveActionMethodParameters( ControllerTypeResolver, mvcNode.Area, mvcNode.Controller, mvcNode.Action); } // Verify route values if (values.Count > 0) { // Checking for same keys and values. if( !CompareMustMatchRouteValues( mvcNode.RouteValues, values ) ) { return false; } foreach( var pair in values ) { if (!string.IsNullOrEmpty(mvcNode[pair.Key])) { if (mvcNode[pair.Key].ToLowerInvariant() == pair.Value.ToString().ToLowerInvariant()) { continue; } else { // Is the current pair.Key a parameter on the action method? if (!actionParameters.Contains(pair.Key, StringComparer.InvariantCultureIgnoreCase)) { return false; } } } else { if (pair.Value == null || string.IsNullOrEmpty(pair.Value.ToString()) || pair.Value == UrlParameter.Optional) { continue; } else if (pair.Key == "area") { return false; } } } } } else { nodeValid = false; } return nodeValid; }
/// <summary> /// Resolves the URL. /// </summary> /// <param name="mvcSiteMapNode">The MVC site map node.</param> /// <param name="area">The area.</param> /// <param name="controller">The controller.</param> /// <param name="action">The action.</param> /// <param name="routeValues">The route values.</param> /// <returns>The resolved URL.</returns> public override string ResolveUrl(MvcSiteMapNode mvcSiteMapNode, string area, string controller, string action, IDictionary<string, object> routeValues) { return base.ResolveUrl(mvcSiteMapNode, area, controller, action, routeValues).ToUpperInvariant(); }
/// <summary> /// Get the attribute value from current node or from the parent nodes /// </summary> /// <param name="attributeName">Name of the attribute</param> /// <param name="xmlNode">Xml node</param> /// <param name="siteMapNode">MvcSiteMapNode to set the attribute to.</param> /// <param name="parentNode">Parent MvcSiteMapNode</param> /// <param name="defaultValue">Default attribute value</param> /// <param name="isRouteValue">If this flag is set to "true", than the attribute value will also be added to routeValues</param> private void LoadInheritedAttribute(string attributeName, XElement xmlNode, MvcSiteMapNode siteMapNode, MvcSiteMapNode parentNode, string defaultValue = null, bool isRouteValue = false) { var value = xmlNode.GetAttributeValue(attributeName); var currentNode = parentNode; while(currentNode != null && string.IsNullOrEmpty(value)) { value = currentNode[attributeName]; currentNode = currentNode.ParentNode as MvcSiteMapNode; } siteMapNode[attributeName] = value ?? defaultValue; if(isRouteValue) { siteMapNode.RouteValues[attributeName] = value ?? defaultValue; } }
/// <summary> /// Resolves the URL. /// </summary> /// <param name="mvcSiteMapNode">The MVC site map node.</param> /// <param name="area">The area.</param> /// <param name="controller">The controller.</param> /// <param name="action">The action.</param> /// <param name="routeValues">The route values.</param> /// <returns>The resolved URL.</returns> public virtual string ResolveUrl(MvcSiteMapNode mvcSiteMapNode, string area, string controller, string action, IDictionary <string, object> routeValues) { if (mvcSiteMapNode["url"] != null) { if (mvcSiteMapNode["url"].StartsWith("~")) { return(System.Web.VirtualPathUtility.ToAbsolute(mvcSiteMapNode["url"])); } else { return(mvcSiteMapNode["url"]); } } if (!string.IsNullOrEmpty(mvcSiteMapNode.PreservedRouteParameters)) { foreach (var item in mvcSiteMapNode.PreservedRouteParameters.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)) { var preservedParameterName = item.Trim(); if (!string.IsNullOrEmpty(preservedParameterName)) { routeValues[preservedParameterName] = UrlHelper.RequestContext.RouteData.Values[preservedParameterName]; } } } //cache already generated routes. //I don't know why the result of Url was not saved to this["url"], perhaps because //theoretically it is possible to change RouteValues dynamically. So I decided to //store last version var key = mvcSiteMapNode.Route ?? string.Empty; foreach (var routeValue in routeValues) { key += routeValue.Key + (routeValue.Value ?? string.Empty); } if (_urlkey == key) { return(_url); } string returnValue = null; if (!string.IsNullOrEmpty(mvcSiteMapNode.Route)) { returnValue = UrlHelper.RouteUrl(mvcSiteMapNode.Route, new RouteValueDictionary(routeValues)); } else { returnValue = UrlHelper.Action(action, controller, new RouteValueDictionary(routeValues)); } if (string.IsNullOrEmpty(returnValue)) { throw new UrlResolverException(string.Format(Messages.CouldNotResolve, mvcSiteMapNode.Title, action, controller, mvcSiteMapNode.Route ?? "")); } _urlkey = key; _url = returnValue; return(returnValue); }
public static SiteMapNodeModel MapToSiteMapNodeModel(SiteMapNode node, MvcSiteMapNode mvcNode, IDictionary<string, object> sourceMetadata) { var model = new SiteMapNodeModel() { Area = mvcNode != null ? mvcNode.Area : "", Controller = mvcNode != null ? mvcNode.Controller : "", Action = mvcNode != null ? mvcNode.Action : "", Title = node.Title, Description = node.Description, TargetFrame = mvcNode == null ? "" : mvcNode.TargetFrame, ImageUrl = mvcNode == null ? "" : mvcNode.ImageUrl, Url = node.Url, IsCurrentNode = node == node.Provider.CurrentNode, IsInCurrentPath = SiteMapNodeExtensions.IsInCurrentPath(node), IsRootNode = node == node.Provider.RootNode, IsClickable = mvcNode == null || mvcNode.Clickable, RouteValues = mvcNode != null ? mvcNode.RouteValues : (IDictionary<string, object>)new Dictionary<string, object>(), MetaAttributes = mvcNode != null ? mvcNode.MetaAttributes : (IDictionary<string, string>)new Dictionary<string, string>(), SourceMetadata = sourceMetadata }; return model; }