1

現在、 Maartenba の 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>
}

_ 編集 _ @Html.MvcSiteMap().SiteMapPath()_Layout から削除して代わりにブログの [インデックス] ビューと [詳細] ビューに配置すると、ブレッドクラムに現在の場所が正しく表示されることがわかりました。

しかし、それは、プロジェクトのすべてのページに配置する必要があることを意味します。これは、_Layout 共有ビューの役割と矛盾しています!

私のコードのどこに間違いがありますか?

4

3 に答える 3

0

インデックスアクションにはidパラメータがあり、それを削除して@Xharzeの提案を適用すると、違いが生じます。ブログ/投稿に固有のルートがweb.configで定義されていますか?

于 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 に答える
0

コントローラー アクションから SiteMapPreserveRouteDataAttribute を削除します。

SiteMapPreserveRouteDataAttribute (現在は廃止されています) は、動的ノードと連携して機能するようには設計されていません。いずれにせよ、RouteValues を動的ノード プロバイダーに明示的に追加しているため、その必要はありません。

于 2013-10-30T09:20:30.313 に答える