/// <summary>
        /// Adds the dynamic nodes for node.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="parentNode">The parent node.</param>
        public IEnumerable <ISiteMapNode> BuildDynamicNodesFor(ISiteMap siteMap, ISiteMapNode node, ISiteMapNode parentNode)
        {
            // List of dynamic nodes that have been created
            var createdDynamicNodes = new List <ISiteMapNode>();

            if (!node.HasDynamicNodeProvider)
            {
                return(createdDynamicNodes);
            }

            // Build dynamic nodes
            foreach (var dynamicNode in node.GetDynamicNodeCollection())
            {
                string key = dynamicNode.Key;
                if (string.IsNullOrEmpty(key))
                {
                    key = nodeKeyGenerator.GenerateKey(
                        parentNode == null ? "" : parentNode.Key,
                        Guid.NewGuid().ToString(),
                        node.Url,
                        node.Title,
                        node.Area,
                        node.Controller,
                        node.Action,
                        node.HttpMethod,
                        node.Clickable);
                }

                // Create a new node
                var newNode = siteMapNodeFactory.CreateDynamic(siteMap, key, node.ResourceKey);

                // Copy the values from the original node to the new one
                node.CopyTo(newNode);

                // Copy any values that were set in the dynamic node and overwrite the new node.
                dynamicNode.SafeCopyTo(newNode);

                // If the dynamic node has a parent key set, use that as the parent. Otherwise use the parentNode.
                if (!string.IsNullOrEmpty(dynamicNode.ParentKey))
                {
                    var parent = siteMap.FindSiteMapNodeFromKey(dynamicNode.ParentKey);
                    if (parent != null)
                    {
                        siteMap.AddNode(newNode, parent);
                        createdDynamicNodes.Add(newNode);
                    }
                }
                else
                {
                    siteMap.AddNode(newNode, parentNode);
                    createdDynamicNodes.Add(newNode);
                }
            }

            // Done!
            return(createdDynamicNodes);
        }
        /// <summary>
        /// Gets the site map node from MVC site map node attribute.
        /// </summary>
        /// <param name="siteMap">The site map.</param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="type">The type.</param>
        /// <param name="methodInfo">The method info.</param>
        /// <returns></returns>
        protected virtual ISiteMapNode GetSiteMapNodeFromMvcSiteMapNodeAttribute(ISiteMap siteMap, IMvcSiteMapNodeAttribute attribute, Type type, MethodInfo methodInfo)
        {
            if (attribute == null)
            {
                throw new ArgumentNullException("attribute");
            }
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (!String.IsNullOrEmpty(attribute.SiteMapCacheKey))
            {
                // Return null if the attribute doesn't apply to this cache key
                if (!this.SiteMapCacheKey.Equals(attribute.SiteMapCacheKey))
                {
                    return(null);
                }
            }

            if (methodInfo == null) // try to find Index action
            {
                var ms = type.FindMembers(MemberTypes.Method, BindingFlags.Instance | BindingFlags.Public,
                                          (mi, o) => mi != null && string.Equals(mi.Name, "Index"), null);
                foreach (MethodInfo m in ms.OfType <MethodInfo>())
                {
                    var pars = m.GetParameters();
                    if (pars.Length == 0)
                    {
                        methodInfo = m;
                        break;
                    }
                }
            }

            string area = "";

            if (!string.IsNullOrEmpty(attribute.AreaName))
            {
                area = attribute.AreaName;
            }
            if (String.IsNullOrEmpty(area) && !String.IsNullOrEmpty(attribute.Area))
            {
                area = attribute.Area;
            }
            // Determine area (will only work if controller is defined as [<Anything>.]Areas.<Area>.Controllers.<AnyController>)
            if (string.IsNullOrEmpty(area))
            {
                var m = Regex.Match(type.Namespace, @"(?:[^\.]+\.|\s+|^)Areas\.(?<areaName>[^\.]+)\.Controllers");
                if (m.Success)
                {
                    area = m.Groups["areaName"].Value;
                }
            }

            // Determine controller and (index) action
            string controller = type.Name.Substring(0, type.Name.IndexOf("Controller"));
            string action     = (methodInfo != null ? methodInfo.Name : null) ?? "Index";

            if (methodInfo != null)
            {
                // handle ActionNameAttribute
                var actionNameAttribute = methodInfo.GetCustomAttributes(typeof(ActionNameAttribute), true).FirstOrDefault() as ActionNameAttribute;
                if (actionNameAttribute != null)
                {
                    action = actionNameAttribute.Name;
                }
            }

            string httpMethod = String.IsNullOrEmpty(attribute.HttpMethod) ? HttpVerbs.Get.ToString().ToUpperInvariant() : attribute.HttpMethod.ToUpperInvariant();

            // Handle title and description
            var title       = attribute.Title;
            var description = String.IsNullOrEmpty(attribute.Description) ? title : attribute.Description;

            // Handle implicit resources
            var implicitResourceKey = attribute.ResourceKey;

            // Generate key for node
            string key = nodeKeyGenerator.GenerateKey(
                null,
                attribute.Key,
                "",
                title,
                area,
                controller, action, httpMethod,
                attribute.Clickable);

            var siteMapNode = siteMapNodeFactory.Create(siteMap, key, implicitResourceKey);

            // Assign defaults
            siteMapNode.Title       = title;
            siteMapNode.Description = description;
            AcquireAttributesFrom(attribute, siteMapNode.Attributes);
            AcquireRolesFrom(attribute, siteMapNode.Roles);
            siteMapNode.Clickable           = attribute.Clickable;
            siteMapNode.VisibilityProvider  = attribute.VisibilityProvider;
            siteMapNode.DynamicNodeProvider = attribute.DynamicNodeProvider;
            siteMapNode.ImageUrl            = attribute.ImageUrl;
            siteMapNode.TargetFrame         = attribute.TargetFrame;
            siteMapNode.HttpMethod          = httpMethod;
            if (!string.IsNullOrEmpty(attribute.Url))
            {
                siteMapNode.Url = attribute.Url;
            }
            siteMapNode.CacheResolvedUrl = attribute.CacheResolvedUrl;
            siteMapNode.CanonicalUrl     = attribute.CanonicalUrl;
            siteMapNode.CanonicalKey     = attribute.CanonicalKey;
            AcquireMetaRobotsValuesFrom(attribute, siteMapNode.MetaRobotsValues);
            siteMapNode.LastModifiedDate = attribute.LastModifiedDate;
            siteMapNode.ChangeFrequency  = attribute.ChangeFrequency;
            siteMapNode.UpdatePriority   = attribute.UpdatePriority;
            siteMapNode.Order            = attribute.Order;

            // Handle route details
            siteMapNode.Route = attribute.Route;
            AcquireRouteValuesFrom(attribute, siteMapNode.RouteValues);
            AcquirePreservedRouteParametersFrom(attribute, siteMapNode.PreservedRouteParameters);
            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);
            }
            if (!string.IsNullOrEmpty(controller))
            {
                siteMapNode.RouteValues.Add("controller", controller);
            }
            if (!string.IsNullOrEmpty(action))
            {
                siteMapNode.RouteValues.Add("action", action);
            }

            // Handle MVC details

            // Add defaults for area
            if (!siteMapNode.RouteValues.ContainsKey("area"))
            {
                siteMapNode.RouteValues.Add("area", "");
            }

            return(siteMapNode);
        }
Example #3
0
        /// <summary>
        /// Maps an XMLElement from the XML file to an MvcSiteMapNode.
        /// </summary>
        /// <param name="node">The element to map.</param>
        /// <param name="parentNode">The parent SiteMapNode</param>
        /// <returns>An MvcSiteMapNode which represents the XMLElement.</returns>
        protected virtual ISiteMapNode GetSiteMapNodeFromXmlElement(ISiteMap siteMap, XElement node, ISiteMapNode parentNode)
        {
            // Get data required to generate the node instance

            // Get area and controller from node declaration or the parent node
            var area                = this.InheritAreaIfNotProvided(node, parentNode);
            var controller          = this.InheritControllerIfNotProvided(node, parentNode);
            var action              = node.GetAttributeValue("action");
            var url                 = node.GetAttributeValue("url");
            var explicitKey         = node.GetAttributeValue("key");
            var parentKey           = parentNode == null ? "" : parentNode.Key;
            var httpMethod          = node.GetAttributeValueOrFallback("httpMethod", HttpVerbs.Get.ToString()).ToUpperInvariant();
            var clickable           = bool.Parse(node.GetAttributeValueOrFallback("clickable", "true"));
            var title               = node.GetAttributeValue("title");
            var implicitResourceKey = node.GetAttributeValue("resourceKey");

            // Generate key for node
            string key = nodeKeyGenerator.GenerateKey(
                parentKey,
                explicitKey,
                url,
                title,
                area,
                controller,
                action,
                httpMethod,
                clickable);

            // Create node
            ISiteMapNode siteMapNode = siteMapNodeFactory.Create(siteMap, key, implicitResourceKey);

            // Assign values
            siteMapNode.Title       = title;
            siteMapNode.Description = node.GetAttributeValue("description");
            siteMapNode.Attributes.AddRange(node, false);
            siteMapNode.Roles.AddRange(node.GetAttributeValue("roles"), new[] { ',', ';' });
            siteMapNode.Clickable           = clickable;
            siteMapNode.VisibilityProvider  = node.GetAttributeValue("visibilityProvider");
            siteMapNode.DynamicNodeProvider = node.GetAttributeValue("dynamicNodeProvider");
            siteMapNode.ImageUrl            = node.GetAttributeValue("imageUrl");
            siteMapNode.ImageUrlProtocol    = node.GetAttributeValue("imageUrlProtocol");
            siteMapNode.ImageUrlHostName    = node.GetAttributeValue("imageUrlHostName");
            siteMapNode.TargetFrame         = node.GetAttributeValue("targetFrame");
            siteMapNode.HttpMethod          = httpMethod;
            siteMapNode.Url = url;
            siteMapNode.CacheResolvedUrl          = bool.Parse(node.GetAttributeValueOrFallback("cacheResolvedUrl", "true"));
            siteMapNode.IncludeAmbientValuesInUrl = bool.Parse(node.GetAttributeValueOrFallback("includeAmbientValuesInUrl", "false"));
            siteMapNode.Protocol             = node.GetAttributeValue("protocol");
            siteMapNode.HostName             = node.GetAttributeValue("hostName");
            siteMapNode.CanonicalKey         = node.GetAttributeValue("canonicalKey");
            siteMapNode.CanonicalUrl         = node.GetAttributeValue("canonicalUrl");
            siteMapNode.CanonicalUrlProtocol = node.GetAttributeValue("canonicalUrlProtocol");
            siteMapNode.CanonicalUrlHostName = node.GetAttributeValue("canonicalUrlHostName");
            siteMapNode.MetaRobotsValues.AddRange(node.GetAttributeValue("metaRobotsValues"), new[] { ' ' });
            siteMapNode.ChangeFrequency  = (ChangeFrequency)Enum.Parse(typeof(ChangeFrequency), node.GetAttributeValueOrFallback("changeFrequency", "Undefined"));
            siteMapNode.UpdatePriority   = (UpdatePriority)Enum.Parse(typeof(UpdatePriority), node.GetAttributeValueOrFallback("updatePriority", "Undefined"));
            siteMapNode.LastModifiedDate = DateTime.Parse(node.GetAttributeValueOrFallback("lastModifiedDate", DateTime.MinValue.ToString()));
            siteMapNode.Order            = int.Parse(node.GetAttributeValueOrFallback("order", "0"));

            // Handle route details

            // Assign to node
            siteMapNode.Route = node.GetAttributeValue("route");
            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;
            siteMapNode.Action     = action;

            // Add inherited route values to sitemap node
            foreach (var inheritedRouteParameter in node.GetAttributeValue("inheritedRouteParameters").Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries))
            {
                var item = inheritedRouteParameter.Trim();
                if (parentNode.RouteValues.ContainsKey(item))
                {
                    siteMapNode.RouteValues.Add(item, parentNode.RouteValues[item]);
                }
            }

            return(siteMapNode);
        }
        /// <summary>
        /// Maps an XMLElement from the XML file to an MvcSiteMapNode.
        /// </summary>
        /// <param name="node">The element to map.</param>
        /// <param name="parentNode">The parent SiteMapNode</param>
        /// <returns>An MvcSiteMapNode which represents the XMLElement.</returns>
        protected virtual ISiteMapNode GetSiteMapNodeFromXmlElement(ISiteMap siteMap, XElement node, ISiteMapNode parentNode)
        {
            //// Get area, controller and action from node declaration
            string area       = node.GetAttributeValue("area");
            string controller = node.GetAttributeValue("controller");

            // Generate key for node
            string key = nodeKeyGenerator.GenerateKey(
                parentNode == null ? "" : parentNode.Key,
                node.GetAttributeValue("key"),
                node.GetAttributeValue("url"),
                node.GetAttributeValue("title"),
                area,
                controller,
                node.GetAttributeValue("action"),
                node.GetAttributeValueOrFallback("httpMethod", "*").ToUpperInvariant(),
                !(node.GetAttributeValue("clickable") == "false"));

            // Handle implicit resources
            var implicitResourceKey = node.GetAttributeValue("resourceKey");

            // Create node
            ISiteMapNode siteMapNode = siteMapNodeFactory.Create(siteMap, key, implicitResourceKey);

            // Handle title and description
            var title       = node.GetAttributeValue("title");
            var description = String.IsNullOrEmpty(node.GetAttributeValue("description")) ? title : node.GetAttributeValue("description");

            // Assign defaults
            siteMapNode.Title       = title;
            siteMapNode.Description = description;
            AcquireAttributesFrom(node, siteMapNode.Attributes);
            AcquireRolesFrom(node, siteMapNode.Roles);
            siteMapNode.Clickable           = bool.Parse(node.GetAttributeValueOrFallback("clickable", "true"));
            siteMapNode.VisibilityProvider  = node.GetAttributeValue("visibilityProvider");
            siteMapNode.DynamicNodeProvider = node.GetAttributeValue("dynamicNodeProvider");
            siteMapNode.ImageUrl            = node.GetAttributeValue("imageUrl");
            siteMapNode.TargetFrame         = node.GetAttributeValue("targetFrame");
            siteMapNode.HttpMethod          = node.GetAttributeValueOrFallback("httpMethod", "*").ToUpperInvariant();
            siteMapNode.Url = node.GetAttributeValue("url");
            siteMapNode.CacheResolvedUrl = bool.Parse(node.GetAttributeValueOrFallback("cacheResolvedUrl", "true"));
            siteMapNode.CanonicalUrl     = node.GetAttributeValue("canonicalUrl");
            siteMapNode.CanonicalKey     = node.GetAttributeValue("canonicalKey");
            this.AcquireMetaRobotsValuesFrom(node, siteMapNode.MetaRobotsValues);
            siteMapNode.ChangeFrequency  = (ChangeFrequency)Enum.Parse(typeof(ChangeFrequency), node.GetAttributeValueOrFallback("changeFrequency", "Undefined"));
            siteMapNode.UpdatePriority   = (UpdatePriority)Enum.Parse(typeof(UpdatePriority), node.GetAttributeValueOrFallback("updatePriority", "Undefined"));
            siteMapNode.LastModifiedDate = DateTime.Parse(node.GetAttributeValueOrFallback("lastModifiedDate", DateTime.MinValue.ToString()));

            // Handle route details

            // Assign to node
            siteMapNode.Route = node.GetAttributeValue("route");
            AcquireRouteValuesFrom(node, siteMapNode.RouteValues);
            AcquirePreservedRouteParametersFrom(node, siteMapNode.PreservedRouteParameters);
            siteMapNode.UrlResolver = node.GetAttributeValue("urlResolver");

            // Add inherited route values to sitemap node
            foreach (var inheritedRouteParameter in node.GetAttributeValue("inheritedRouteParameters").Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries))
            {
                var item = inheritedRouteParameter.Trim();
                if (parentNode.RouteValues.ContainsKey(item))
                {
                    siteMapNode.RouteValues.Add(item, parentNode.RouteValues[item]);
                }
            }

            // Handle MVC details

            // Inherit area and controller from parent
            if (parentNode != null)
            {
                if (string.IsNullOrEmpty(area))
                {
                    siteMapNode.Area = parentNode.Area;
                }
                if (string.IsNullOrEmpty(controller))
                {
                    siteMapNode.Controller = parentNode.Controller;
                }
            }

            // Add defaults for area
            if (!siteMapNode.RouteValues.ContainsKey("area"))
            {
                siteMapNode.RouteValues.Add("area", "");
            }

            return(siteMapNode);
        }