Asp.net mvc MvcSiteMapProvider IsItemMapBuilder与IDynamicNodeProvider联合使用
我正在使用MVCSItemApprovider4.4.3从数据库动态构建站点地图。我关注这篇文章:因为我正在使用多个站点地图 这是有效的,这是返回的基本结构:Asp.net mvc MvcSiteMapProvider IsItemMapBuilder与IDynamicNodeProvider联合使用,asp.net-mvc,mvcsitemapprovider,Asp.net Mvc,Mvcsitemapprovider,我正在使用MVCSItemApprovider4.4.3从数据库动态构建站点地图。我关注这篇文章:因为我正在使用多个站点地图 这是有效的,这是返回的基本结构: 家 新闻 产品 关于 接触 其中一个节点(/Products)应根据不同的数据再次动态填充。因此,我需要在/Products节点上实现IDynamicNodeProvider?(如果我错了,请纠正我) 不管怎样,我想我确实需要以上这些。文档显示了在XML中定义的节点和使用控制器操作属性定义的节点上执行此操作的方法,但不是在ISit
- 家
- 新闻
- 产品
- 关于
- 接触
/Products
)应根据不同的数据再次动态填充。因此,我需要在/Products
节点上实现IDynamicNodeProvider
?(如果我错了,请纠正我)
不管怎样,我想我确实需要以上这些。文档显示了在XML中定义的节点和使用控制器操作属性定义的节点上执行此操作的方法,但不是在ISiteMapBuilder
中“手动”执行。因此,如果我设置ISiteMapNode
实例的.dynamicondeprovider
属性,它似乎不会被实例化。。。.HasDynamicNodeProvider
属性还返回false
查看源代码,我看到了PluginProvider
——与dynamicondeproviderstrategy
相关的东西,你看,他们把我弄丢了
如何在我的
ISiteMapBuilder
中为“/Products
”创建一个ISiteMapNode
,使其子代(/Products/Cat
和/Products/Cat/Product
)从数据库中动态加载?/p>您可以使用ISiteMapBuilder执行此操作,但您最好还是实现ISitemApodeProvider。原因是,向站点地图添加节点必须在实例化所有节点后的最后一刻完成,以确保每个节点都正确映射到父节点(当然,不需要父节点的根节点除外)。这是在4.3.0中完成的主要设计更改
现在已经设置了默认的SiteMapBuilder类,以确保
public interface ISiteMapNodeProvider
{
IEnumerable<ISiteMapNodeToParentRelation> GetSiteMapNodes(ISiteMapNodeHelper helper);
}
public class CustomSiteMapNodeProvider
: ISiteMapNodeProvider
{
private readonly string sourceName = "CustomSiteMapNodeProvider";
#region ISiteMapNodeProvider Members
public IEnumerable<ISiteMapNodeToParentRelation> GetSiteMapNodes(ISiteMapNodeHelper helper)
{
var result = new List<ISiteMapNodeToParentRelation>();
using (var db = new DatabaseContextClass())
{
foreach (var category in db.Categories.ToList())
{
var categoryRelation = this.GetCategoryRelation("Products", category, helper);
result.Add(categoryRelation);
}
foreach (var product in db.Products.Include("Category"))
{
var productRelation = this.GetProductRelation("Category_" + product.CategoryId, product, helper);
result.Add(productRelation);
}
}
return result;
}
#endregion
protected virtual ISiteMapNodeToParentRelation GetCategoryRelation(string parentKey, Category category, ISiteMapNodeHelper helper)
{
string key = "Category_" + category.Id;
var result = helper.CreateNode(key, parentKey, this.sourceName);
var node = result.Node;
node.Title = category.Name;
// Populate other node properties here
// Important - always set up your routes (including any custom params)
node.Area = "MyArea"; // Required - set to empty string if not using areas
node.Controller = "Category"; // Required
node.Action = "Index"; // Required
node.RouteValues.Add("id", category.Id.ToString());
return result;
}
protected virtual ISiteMapNodeToParentRelation GetProductRelation(string parentKey, Product product, ISiteMapNodeHelper helper)
{
string key = "Product_" + product.Id;
var result = helper.CreateNode(key, parentKey, this.sourceName);
var node = result.Node;
node.Title = product.Name;
// Populate other node properties here
// Important - always set up your routes (including any custom params)
node.Area = "MyArea"; // Required - set to empty string if not using areas
node.Controller = "Product"; // Required
node.Action = "Index"; // Required
node.RouteValues.Add("id", product.Id.ToString());
node.RouteValues.Add("categoryId", product.CategoryId.ToString()); // Optional - use if you have a many-to-many relationship.
return result;
}
}
公共接口IsItemaNodeProvider
{
IEnumerable GetSiteMapNodes(ISiteMapNodeHelper);
}
只有一种方法需要实现。此外,许多常见(但可选)服务是通过接口从SiteMapBuilder类通过ISiteMapNodeHelper自动注入的
该类的级别低于IDynamicNodeProvider。您直接与ISiteMapNode交互,但与SiteMap类的所有交互都由SiteMapBuilder处理。ISiteMapNode被包装在一个ISiteMapNodeToParentRelation实例中,该实例用于确保在将其添加到SiteMap对象之前可以跟踪其父节点密钥
您的SiteMapNodeProvider应该如下所示:
public interface ISiteMapNodeProvider
{
IEnumerable<ISiteMapNodeToParentRelation> GetSiteMapNodes(ISiteMapNodeHelper helper);
}
public class CustomSiteMapNodeProvider
: ISiteMapNodeProvider
{
private readonly string sourceName = "CustomSiteMapNodeProvider";
#region ISiteMapNodeProvider Members
public IEnumerable<ISiteMapNodeToParentRelation> GetSiteMapNodes(ISiteMapNodeHelper helper)
{
var result = new List<ISiteMapNodeToParentRelation>();
using (var db = new DatabaseContextClass())
{
foreach (var category in db.Categories.ToList())
{
var categoryRelation = this.GetCategoryRelation("Products", category, helper);
result.Add(categoryRelation);
}
foreach (var product in db.Products.Include("Category"))
{
var productRelation = this.GetProductRelation("Category_" + product.CategoryId, product, helper);
result.Add(productRelation);
}
}
return result;
}
#endregion
protected virtual ISiteMapNodeToParentRelation GetCategoryRelation(string parentKey, Category category, ISiteMapNodeHelper helper)
{
string key = "Category_" + category.Id;
var result = helper.CreateNode(key, parentKey, this.sourceName);
var node = result.Node;
node.Title = category.Name;
// Populate other node properties here
// Important - always set up your routes (including any custom params)
node.Area = "MyArea"; // Required - set to empty string if not using areas
node.Controller = "Category"; // Required
node.Action = "Index"; // Required
node.RouteValues.Add("id", category.Id.ToString());
return result;
}
protected virtual ISiteMapNodeToParentRelation GetProductRelation(string parentKey, Product product, ISiteMapNodeHelper helper)
{
string key = "Product_" + product.Id;
var result = helper.CreateNode(key, parentKey, this.sourceName);
var node = result.Node;
node.Title = product.Name;
// Populate other node properties here
// Important - always set up your routes (including any custom params)
node.Area = "MyArea"; // Required - set to empty string if not using areas
node.Controller = "Product"; // Required
node.Action = "Index"; // Required
node.RouteValues.Add("id", product.Id.ToString());
node.RouteValues.Add("categoryId", product.CategoryId.ToString()); // Optional - use if you have a many-to-many relationship.
return result;
}
}
公共类CustomSiteMapNodeProvider
:IsItemaNodeProvider
{
私有只读字符串sourceName=“CustomSiteMapNodeProvider”;
#区域IsItemaNodeProvider成员
公共IEnumerable GetSiteMapNodes(ISiteMapNodeHelper)
{
var result=新列表();
使用(var db=new DatabaseContextClass())
{
foreach(db.Categories.ToList()中的变量类别)
{
var categoryRelation=this.GetCategoryRelation(“产品”、类别、助手);
结果。添加(类别关系);
}
foreach(db.Products.Include(“类别”)中的var产品)
{
var productRelation=this.GetProductRelation(“Category_u”+product.CategoryId,product,helper);
结果.添加(productRelation);
}
}
返回结果;
}
#端区
受保护的虚拟ISitemApodeToParentRelation GetCategoryRelation(字符串parentKey、类别Category、ISitemApodeHelper)
{
string key=“Category\”+Category.Id;
var result=helper.CreateNode(key、parentKey、this.sourceName);
var node=result.node;
node.Title=category.Name;
//在此处填充其他节点属性
//重要信息-始终设置路由(包括任何自定义参数)
node.Area=“MyArea”;//必需-如果不使用区域,则设置为空字符串
node.Controller=“Category”;//必需
node.Action=“Index”;//必需
Add(“id”,category.id.ToString());
返回结果;
}
受保护的虚拟ISitemApodeToParentRelation GetProductRelation(字符串parentKey、产品产品、ISitemApodeHelper)
{
string key=“Product\”+Product.Id;
var result=helper.CreateNode(key、parentKey、this.sourceName);
var node=result.node;
node.Title=product.Name;
//在此处填充其他节点属性
//重要信息-始终设置路由(包括任何自定义参数)
node.Area=“MyArea”;//必需-如果不使用区域,则设置为空字符串
node.Controller=“Product”//必需
node.Action=“Index”;//必需
添加(“id”,product.id.ToString());
node.RouteValues.Add(“categoryId”,product.categoryId.ToString());//可选-使用i