我目前正在使用Maartenba's MVC Sitemap Provider在MVC3 Razor应用程序中实现breadcrumb。当我尝试为博客帖子创建动态节点时,会出现问题。我想要实现的是为博客页面显示 Home> Blog ,为帖子页面显示 Home> Blog> BlogPostTitle ,其中 BlogPostTitle 是当前显示的帖子的标题。我实际得到的是:主页>博客,包括博客页面和任何帖子页面。
为了测试动态节点的生成,我还在_Layout中包含了对@Html.MvcSiteMap()的调用.Menu(false,true,true)。显示的菜单确认节点已正确生成:
仍然,@ Html.MvcSiteMap()。SiteMapPath()为博客页面和文章显示 Home> Blog 。
以下是代码:
网页:
<mvcSiteMapNode title="Home" controller="Home" action="Index">
<mvcSiteMapNode title="About" controller="Home" action="About"/>
<mvcSiteMapNode title="Blog" controller="BlogPost" action="Index" key="News" >
<mvcSiteMapNode title="" controller="BlogPost" action="Details" dynamicNodeProvider ="MyApp.Helpers.BlogPostDynamicNodeProvider, myApp" />
</mvcSiteMapNode>
<mvcSiteMapNode title="Contact" controller="Home" action="Contact"/>
</mvcSiteMapNode>
动态节点提供商:
public class BlogPostDynamicNodeProvider : DynamicNodeProviderBase
{
public BlogPostRepository _repository = new BlogPostRepository();
public List<BlogPost> articles = new List<BlogPost>();
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
articles = _repository.FindAllBlogPosts();
var returnValue = new List<DynamicNode>();
foreach (var article in articles)
{
DynamicNode node = new DynamicNode();
node.ParentKey = "News";
node.Title = article.PostTitle;
node.RouteValues.Add("id", article.Post_ID);
returnValue.Add(node);
}
return returnValue;
}
public override CacheDescription GetCacheDescription()
{
return new CacheDescription("BlogPostDynamicNodeProvider")
{
SlidingExpiration = TimeSpan.FromMinutes(1)
};
}
}
BlogPostCOntroller
public ViewResult Index(long? BlogPost_ID)
{
var BlogPostList = new PagedData<BlogPost>();
BlogPostList.Data = repository.FindAllBlogPostsPaged(1, 3, 1);
BlogPostList.NumberOfPages = Convert.ToInt32(Math.Ceiling((double)repository.NumberOfPosts(1) / 3));
BlogPostList.CurrentPage = 1;
BlogPost pBlogPost = new BlogPost();
pBlogPost.PostDate = DateTime.Now;
return View(new BlogPostPagedViewModel(pBlogPost, repository.FindAllBlogPosts()
new SelectList(ctgRepository.FindAllBlogCategories(), "Category_ID", "Category_Name")));
}
[SiteMapPreserveRouteData]
public ActionResult Details(long id)
{
BlogPost post = repository.FindABlogPostByID(id);
return PartialView("_Details", post);
}
_layout
<div id="pagecontent">
@Html.MvcSiteMap().Menu(false, true, true) <!-- for test purpose only -->
@Html.MvcSiteMap().SiteMapPath()
@Html.Partial("_PagedList", Model.BlogPostList)
</div><!-- page blogcontent -->
博客索引视图
<div id="blogcontent">
@Html.Partial("_PagedList", Model.BlogPostList)
</div><!-- end blogcontent -->
博客_PagedList局部视图
@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "blogcontent", InsertionMode = InsertionMode.Replace }))
{
foreach (var item in Model.Data)
{
<h2 class="posttitle">
@Ajax.ActionLink(item.PostTitle, "Details", "BlogPost", new { id = item.Post_ID }, new AjaxOptions { UpdateTargetId = "blogcontent" }, null)
</h2>
}
}
详情视图
@model MyApp.Models.BlogPost
@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "blogcontent", InsertionMode = InsertionMode.Replace }))
{
<div class="blogpost">
...
</div>
}
_编辑_
我发现,如果我从_Layout中删除@Html.MvcSiteMap().SiteMapPath()
并将其放在博客索引视图和详细信息视图中,则痕迹导线会正确显示当前位置。
但这意味着我需要将它放在项目的每个页面上,这与_Layout共享视图的角色相矛盾!
我的代码中的错误在哪里?
答案 0 :(得分:0)
在创建DynamicNode时尝试设置Controller和Action:
DynamicNode node = new DynamicNode();
node.Controller = "ControllerName";
node.Action = "ActionName";
node.ParentKey = "News";
node.Title = article.PostTitle;
node.RouteValues.Add("id", article.Post_ID);
returnValue.Add(node);
此信息用于选择正确的路线。
答案 1 :(得分:0)
在你的索引操作中你有一个id参数,如果你删除它并应用@Xharze建议,那会有什么不同。您是否在web.config中定义了特定于博客/帖子的任何路由?
答案 2 :(得分:0)
从控制器操作中删除SiteMapPreserveRouteDataAttribute。
SiteMapPreserveRouteDataAttribute(现已弃用)不适用于与动态节点配合使用。并且没有必要,因为无论如何都要在动态节点提供程序中明确添加RouteValues。