1

我目前正在使用Maartenba 的 MVC Sitemap Provider在 MVC3 Razor 应用程序中实现面包屑。当我尝试为博客文章创建动态节点时,就会出现问题。我想要实现的是为博客页面显示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)
        };
    }
}

博客帖子控制器

    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);
    }

_布局

<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>
}

_ 编辑 _ 我发现,如果我@Html.MvcSiteMap().SiteMapPath()从 _Layout 中删除并将其放置在博客索引视图和详细信息视图中,则面包屑会正确显示当前位置。

但这意味着我需要将它放在项目的每个页面上,这与 _Layout 共享视图的作用相矛盾!

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

4

3 回答 3

0

从控制器操作中删除 SiteMapPreserveRouteDataAttribute。

SiteMapPreserveRouteDataAttribute(现已弃用)并非旨在与动态节点一起使用。而且没有必要,因为无论如何您都在动态节点提供程序中显式添加 RouteValues。

于 2013-10-30T09:20:30.313 回答
0

在您的 Index 操作中,您有一个 id 参数,如果您删除它并应用@Xharze 建议,这有什么不同。您是否在 web.config 中定义了特定于 blogs/posts 的任何路由?

于 2012-12-13T14:05:05.373 回答
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);

此信息用于选择正确的路线。

于 2012-10-12T11:00:33.053 回答