MVCSiteMapProvider动态节点未显示

时间:2012-10-11 23:34:42

标签: asp.net-mvc-3 mvcsitemapprovider

我目前正在使用Maartenba's MVC Sitemap Provider在MVC3 Razor应用程序中实现breadcrumb。当我尝试为博客帖子创建动态节点时,会出现问题。我想要实现的是为博客页面显示 Home> Blog ,为帖子页面显示 Home> Blog> BlogPostTitle ,其中 BlogPostTitle 是当前显示的帖子的标题。我实际得到的是:主页>博客,包括博客页面和任何帖子页面。

为了测试动态节点的生成,我还在_Layout中包含了对@Html.MvcSiteMap()的调用.Menu(false,true,true)。显示的菜单确认节点已正确生成:

  • 主页
  • 关于
  • 博客
    • 文章#1标题
    • 第2条标题
  • 联系

仍然,@ 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共享视图的角色相矛盾!

我的代码中的错误在哪里?

3 个答案:

答案 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。