MvcSiteMapProvider not generating correct URLs in dynamic nodes
-
21-12-2019 - |
Question
I wrote a dynamic node provider that looks like so:
public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
{
var dictionaryDefs = from d in provider.GetDictionaries()
orderby d.DisplayNamePlural
select d;
foreach (DictionaryInfo di in dictionaryDefs)
{
var newNode = new DynamicNode()
{
Title = di.DisplayNamePlural,
Description = "Import " + di.DisplayNamePlural,
ParentKey = "Import Records"
};
newNode.Attributes.Add("entity",di.DictionaryName);
yield return newNode;
}
}
My template node looks like (namespace and assembly names anonymized):
<mvcSiteMapNode title ="ToBeReplaced" route="CMS_EntityAction" controller="ImportDictionary" action="Import" crudlevel="Update" dynamicNodeProvider="NameSpace.INeedToImportDataNodeProvider, MyAssembly"/>
And here is the Route I specified for it to use:
routes.MapRoute(
"CMS_EntityAction", // Route name
"{controller}/{action}/{entity}",
new { action = "Index", controller = "Grid", showCheckboxes = UrlParameter.Optional },
new { controller = @"(Grid|ImportDictionary)" }
);
Note that the dynamic node provider supplies the entity
value, but the controller and action are to be inherited from the template.
All I get for Urls, though is "#", which from what I can tell in skimming the source, means the UrlResolver couldn't resolve the Url.
If I remove the specific route name from the template node (route="CMS_EntityAction"
) then it just generates the same URL over and over again for each node which is /ImportDictionary/Import
which is missing the entity
value as the 3rd segment.
I've tried specifying the controller and action in the dynamic node provider instead of the template and I get the same thing, it just will not use the value of entity
in creating the URL.
Any ideas of what I need to change, specify or fix? Thanks.
(Please don't judge me on that ShowCheckboxes thing, it's out of my hands :-) )
Solution
The problem is that you are not adding the "entity" to the RouteValues collection of the node, but you are instead adding it to Attributes, making it a custom attribute value. Custom attributes are not taken into consideration when generating the URL.
If you change:
newNode.Attributes.Add("entity",di.DictionaryName);
To:
newNode.RouteValues.Add("entity",di.DictionaryName);
Then the entity argument will be inserted into the URL.