【问题标题】:MVCSiteMapProvider dynamic nodes not showingMVCSiteMapProvider 动态节点未显示
【发布时间】:2012-10-11 23:34:42
【问题描述】:

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

为了测试动态节点的生成,我还在_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>
}

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

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

我的代码哪里出错了?

【问题讨论】:

    标签: asp.net-mvc-3 mvcsitemapprovider


    【解决方案1】:

    在创建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);
    

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

    【讨论】:

    • 感谢您的回答,不幸的是,应用您的建议不会改变上述行为。
    【解决方案2】:

    在您的索引操作中,您有一个 id 参数,如果您删除该参数并应用@Xharze 建议,这有什么不同。您是否在 web.config 中定义了特定于博客/帖子的路由?

    【讨论】:

      【解决方案3】:

      从您的控制器操作中删除 SiteMapPreserveRouteDataAttribute。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-21
        • 2011-05-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多