Create/remove sitemap node in ActionResult

Aug 25, 2010 at 4:29 PM

Posted this in StackOverflow, no response... http://stackoverflow.com/questions/3547955/create-remove-sitemap-node-in-actionresult-asp-net-mvc-sitemap-provider 
So copying over and hoping for a response... 

I am using the ASP.NET MVC SiteMap provider to create dynamic sitemap nodes. It works when the application is first loaded, but I wish to add/remove nodes when an ActionResult executes (to add/remove a record from the database). My web.sitemap is as follows (taken out the parent node and other siblings)

 

<mvcSiteMapNode dynamicNodeProvider="MyWebSite.DynamicNodeProvider.DatesDynamicNodeProvider, MyWebSite">
    <mvcSiteMapNode action="Details" dynamicNodeProvider="MyWebSite.DynamicNodeProvider.DetailsDynamicNodeProvider, MyWebSite" />
    <mvcSiteMapNode action="Edit" dynamicNodeProvider="MyWebSite.DynamicNodeProvider.EditDynamicNodeProvider, MyWebSite" />
    <mvcSiteMapNode action="Delete" dynamicNodeProvider="MyWebSite.DynamicNodeProvider.DeleteDynamicNodeProvider, MyWebSite" />
</mvcSiteMapNode>

 

The dates are generated dynamically:

 

    public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
    {
        DBDataContext db = new DBDataContext();

        var records = db.records.ToList();
        if (records != null)
        {
            DateTime created;
            foreach (var record in records)
            {
                if (record.DateCreated.HasValue)
                {
                    created = record.DateCreated.Value;
                    DynamicNode node = CreateNode(created);
                    yield return node;
                }

            }
        }
    }

    public static DynamicNode CreateNode(DateTime date)
    {
        DynamicNode node = new DynamicNode("record_" + date.ToString("yyyy-M"), date.ToString("MMMM yyyy"));
        node.Action = date.ToString("yyyy-M");
        node.ParentKey = "records";
        return node;
    }

 

And then add nodes under these generated nodes:

 

    public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
    {
        DBDataContext db = new DBDataContext();

        var records = db.records.ToList();
        if (records != null)
        {
            // Create a node for each record
            foreach (var record in records)
            {
                if (record.DateCreated.HasValue)
                {
                    DynamicNode node = CreateNode(record);

                    yield return node;
                }
            }
        }
    }

    public static DynamicNode CreateNode(Record record)
    {
        DateTime created = record.DateCreated.Value;
        DynamicNode node = new DynamicNode("record_edit_" + record.ID, string.Format("{0:dd MMM yyyy}: {1} (Edit)", created, record.Title));
        node.RouteValues["id"] = record.ID;
        node.ParentKey = "record_" + created.ToString("yyyy-M");

        return node;
    }

 

However, I then get to the point of creating these nodes within an ActionResult, but get stuck at this point. I can grab the node:

 

var node = ((MvcSiteMapProvider.DefaultSiteMapProvider)SiteMap.Provider).FindSiteMapNodeFromKey("record_edit_" + record.ID);

 

But then I want to check if the node is null, and if not create a new one (and the parent node if it does not exist). First thing I tried doesn't work, as not sure if you can add a DynamicNode to the site map (as I can't cast DynamicNode to SiteMapNode)

if (node == null)
    {
        node = DynamicNodeProvider.EditDynamicNodeProvider.CreateNode(record) as SiteMapNode;
        var parent = ((MvcSiteMapProvider.DefaultSiteMapProvider)SiteMap.Provider).FindSiteMapNodeFromKey("record_" + record.DateCreated.Value.ToString("yyyy-M"));
        if (parent == null)
        {
            parent = DynamicNodeProvider.DatesDynamicNodeProvider.CreateNode(record.DateCreated.Value) as SiteMapNode;
            parent.Action = record.DateCreated.Value.ToString("yyyy-M");
            parent.ParentKey = "records";
        }
        node.ParentKey = parent.ParentKey;
    }

Of course, this doesn't work because of the aforementioned problem.

This is just for the edit page for each record, I also want change the title (if the title is changed) or delete from the sitemap if necessary.

Any ideas?

 

 

 

 

Coordinator
Aug 26, 2010 at 1:02 PM

Try setting the cache dependency on your dynamic node providers and have them trigger a sitemap update when needed (for example when a record is added).

Oct 26, 2010 at 10:10 AM

maartenba, how we can trigger a sitemap update from action. When I try Clear() and add child from BuildSiteMap() - it brokes with readonly issue.

Coordinator
Oct 26, 2010 at 10:25 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.