问题
I implement IDynamicNodeProvider according to this https://github.com/maartenba/MvcSiteMapProvider/wiki/Defining-sitemap-nodes-using-IDynamicNodeProvider
I would like to change the parent Key dynamically. I have a lot of parent nodes according to my menu navigation. Some example is
1) Home>Profile>Quality Policy
2) Home>eServices>eService
I have two tables. In the first one I keep my menus. MenuID, MenuTitle and in the other I store my content. ArticleID, ArticleTitle, ArticleContent, MenuID.
I need to change the parent Key dynamically.
This is my class
public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
{
webdata storeDB = new webdata();
var returnValue = new List<DynamicNode>();
foreach (var article in storeDB.SiteContents)
{
DynamicNode enode = new DynamicNode();
enode.Title = article.ArticleTitle;
enode.ParentKey = "?";
//Specify Controller and Action name
enode.Controller = "SiteContents";
enode.Action = "ArticleDetails";
enode.RouteValues.Add("id", article.ArticleID);
enode.PreservedRouteParameters.Add("slug");
returnValue.Add(enode);
yield return enode;
}
}
My sitemap file
<mvcSiteMapNode title="Home" controller="Home" action="Index">
<mvcSiteMapNode controller="SiteContents" dynamicNodeProvider="Myproject.Models.ElkeDynamicNodeProvider, Myproject" />
</mvcSiteMapNode>
How can I join the two tables so to bring the MenuTitle as a parentKey and how this will be linked at the right action. Thank you
回答1:
It is not possible to have more than one parent per node or to change the parent key dynamically.
I am not sure exactly what you are trying to achieve by this, but do note that it is possible to have multiple navigation paths to a page by providing 2 unique URLs to that page and using canonicalKey
or canonicalUrl
on one of them to prevent search engines from penalizing you.
Also note that you could in fact use a variation of the primary and/or foreign keys in your database to create the nodes. So if you have the relationship in your database, you can just create dynamic nodes based on that same relationship.
For example, if you have a MenuID
in your Article
table (or can join the tables to get a corresponding MenuID
, you just need to loop through each table and create a key based off of MenuID
(such as MenuID1234
) that is used for the key of the menu entity and the parent key of the article entity. Each article would then have a key ArticleID3456
, which could be used as a parent key of the next level.
Example
public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
{
// I am assuming here that webdata is your
// Entity Framework context class. If so,
// you should wrap it in a using block.
using (webdata storeDB = new webdata())
{
// Loop through your Menu Table
foreach (var menuItem in storeDB.Menu)
{
DynamicNode enode = new DynamicNode();
enode.Title = menuItem.MenuTitle;
// I am assuming that you want your menu categories below the home page
// and that that node has a key="Home" attribute set.
enode.ParentKey = "Home";
// Specify the key based on the primary key in the DB
// Cast to a string if necessary.
enode.Key = "MenuID" + menuItem.MenuID;
// Specify Controller and Action name
// (not sure where you want to navigate to here)
enode.Controller = "SiteContents";
enode.Action = "ArticleDetails";
enode.RouteValues.Add("id", menuItem.MenuID);
// If your menu categories don't represent
// real pages, you can use non-clickable nodes
// instead of controller, action, and id.
//enode.Clickable = false;
// Add this if you use a slug on these pages
enode.PreservedRouteParameters.Add("slug");
yield return enode;
}
// Loop through your Article Table
foreach (var article in storeDB.Article)
{
DynamicNode enode = new DynamicNode();
enode.Title = article.ArticleTitle;
// Attach to your foreign key, the same way as in your DB
enode.ParentKey = "MenuID" + article.MenuID;
// Give your article a sensible unique key.
// This will save some memory and make it easy
// to add a level below the article if needed.
enode.Key = "ArticleID" + article.ArticleID;
//Specify Controller and Action name
enode.Controller = "SiteContents";
enode.Action = "ArticleDetails";
enode.RouteValues.Add("id", article.ArticleID);
enode.PreservedRouteParameters.Add("slug");
yield return enode;
}
}
}
来源:https://stackoverflow.com/questions/35717293/change-parent-key-dynamically-idynamicnodeprovider-mvc