/// <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;
        }
Example #2
0
        /// <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)
                {
                    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;
        }