Dynamic parameters depends on their order in the code

Oct 28, 2009 at 3:41 AM

if declare two dynamic parameters

        [MvcSiteMapNode(ParentKey = "Product", Key = "ProductCategory", IsDynamic = true, DynamicParameters = "catId", Visibility = MvcSiteMapNodeVisibility.InSiteMapPathOnly)]
        public ActionResult Cat(int catId, int? page)
        {

        }

 

        [MvcSiteMapNode(ParentKey = "ProductCategory", IsDynamic = true, DynamicParameters = "id", Visibility = MvcSiteMapNodeVisibility.InSiteMapPathOnly)]
        public ActionResult Details(int id)
        {

        }

 

"Product" node declare in  web.sitemap

if we put Details method to the front of the Cat method in the code, it will not work well.

Coordinator
Oct 29, 2009 at 1:06 PM

Can you post some code to reproduce this?

Oct 29, 2009 at 1:34 PM

the follow is my codes:

 

      [MvcSiteMapNode(ParentKey = "Product", Key = "ProductCategory", IsDynamic = true, DynamicParameters = "catId", Visibility = MvcSiteMapNodeVisibility.InSiteMapPathOnly)]
        public ActionResult Cat(int catId, int? page)
        {
            int pageIndex = page.HasValue && page.Value > 1 ? page.Value : 1;

            var model = new ProductListByCategoryModel(_siteService, _productService, catId, pageIndex);

            SiteMap.CurrentNode.Title = model.Category.Name;

            return this.View(model);
        }

        [MvcSiteMapNode(ParentKey = "ProductCategory", IsDynamic = true, DynamicParameters = "id", Visibility = MvcSiteMapNodeVisibility.InSiteMapPathOnly)]
        public ActionResult Details(int id)
        {
            var model = new ProductDetailsModel(_siteService, _productService, _viewHistoryStorage, id);

            var product = model.MyProduct;

            // Set sitemap
            SiteMap.CurrentNode.Title = product.Name;

            SiteMap.CurrentNode.ParentNode.Title = product.Category.Name;
            SiteMap.CurrentNode.ParentNode.Url = Url.ProductCategory(product.Category);

            return this.View(model);
        }

 

if i put the Details method to the front of the Cat method in the code, and access action like this /Product/Details/1,  it will change root node's title to the current product's category name.

 

i think the reason is in the class MvcSiteMapProvider's ProcessNodesInAssembly method:

                foreach (MethodInfo method in type.Key.GetMethods(BindingFlags.Public | BindingFlags.Instance))
                {
                    foreach (MvcSiteMapNodeAttribute attribute in (MvcSiteMapNodeAttribute[])method.GetCustomAttributes(typeof(MvcSiteMapNodeAttribute), true))
                    {
                        SiteMapNode node = GetMvcSiteMapNodeFromMvcSiteMapNodeAttribute(attribute, type.Key, method);
                        SiteMapNode parentNode = (controllerNode != null && string.IsNullOrEmpty(attribute.ParentKey)) ?
                                                    controllerNode :
                                                    (string.IsNullOrEmpty(attribute.ParentKey) ? this.rootNode : FindSiteMapNodeFromKey(attribute.ParentKey, false));
                        parentNode = parentNode ?? this.rootNode;
                        if (node != null && parentNode != null)
                        {
                            AddNode(node, parentNode);
                        }
                    }
                }

 

when put Details method to the front of the Cat method, in that time, we still can not find the node with key eq "ProductCategory" as its parentNode, and its parentNode will be set to the rootNode. that is not right.

we should add node with key "ProductCategory" first.