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?