この記事では、MvcSiteMapProviderを使用して動的メニューを作成する方法、それを使用してサイトマップと「ブレッドクラム」を作成する方法を示します。
MVC Music StoreトレーニングプロジェクトでMvcSiteMapProviderを使用する方法を示します。
サイト構造は次のとおりです
ホーム
店
ロック
職場で最高の男性職場で最高の男性
ロックしようとしている人のために
クラシック
ジャズ
...
管理者
MvcSiteMapProviderのソースは、MS-PLライセンスのGithubにあります。
nugetを使用してプロジェクトにインストールする(表示->他のウィンドウ->パッケージマネージャーコンソール)
PM>インストールパッケージMvcSiteMapProvider
このパッケージをインストールすると、Views / Shared / DisplayTemplatesフォルダーに新しいビューが表示されます。
不要な* .ascxファイルを削除しました。
また、プロジェクトのルートにMvc.sitemapとMvcSiteMapSchema.xsdが表示されます。
次の行がweb.configに追加されます。
<siteMap defaultProvider="MvcSiteMapProvider" enabled="true"> <providers> <clear /> <add name="MvcSiteMapProvider" type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" siteMapFile="~/Mvc.Sitemap" securityTrimmingEnabled="true" cacheDuration="5" enableLocalization="true" scanAssembliesForSiteMapNodes="true" includeAssembliesForScan="" excludeAssembliesForScan="" attributesToIgnore="visibility" nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider" controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider" actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider" aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider" siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider" siteMapNodeVisibilityProvider="MvcSiteMapProvider.DefaultSiteMapNodeVisibilityProvider, MvcSiteMapProvider" siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider" /> </providers> </siteMap> </code>
まず、Mvc.sitemapに興味があります。デフォルトでは次のようになります。
<?xml version="1.0" encoding="utf-8" ?> <mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0 MvcSiteMapSchema.xsd" enableLocalization="true"> <mvcSiteMapNode title="Home" controller="Home" action="Index"> <mvcSiteMapNode title="About" controller="Home" action="About"/> </mvcSiteMapNode> </mvcSiteMap>
mvcSiteMapNode xml要素は、サイトマップの主要な要素です。 その主な属性:
- title-ブラウザーに表示されるアイテムの名前
- コントローラー -コントローラー、ルートから
- action-アクション、ルートから
- エリア -ルートからのエリア(エリア)
- dynamicNodeProvider-このノードの代わりにmvcSiteMapセットを生成するクラス
- 可視性 -ノードの可視性、サイトマップのみ、またはメニューまたは他のオプションのみ
サイトの構造に対応するノードを追加しました:
<?xml version="1.0" encoding="utf-8" ?> <mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0 MvcSiteMapSchema.xsd" enableLocalization="true"> <mvcSiteMapNode title="Home" controller="Home" action="Index"> <mvcSiteMapNode title="Store" controller="Store" action="Index"> </mvcSiteMapNode> <mvcSiteMapNode title="Cart" controller="ShoppingCart" action="Index" /> <mvcSiteMapNode title="Admin" controller="StoreManager" action="Index" > </mvcSiteMapNode> </mvcSiteMapNode> </mvcSiteMap>
ここには4つのメインページのみが追加されています。 次に、サイトマップにジャンルとアルバムを追加する必要があります。
- ロック
- 職場で最高の男性職場で最高の男性
- ロックしようとしている人のために
- ...
- クラシック
- ジャズ
- ...
なぜなら 当社のサイトは動的であるため、アルバムとジャンルは常に変化し、静的なサイトマップは機能しません。 この問題を解決するために、MvcSiteMapProviderにはdynamicNodeProviderがあります。 したがって、 DynamicNodeProviderBaseから継承したクラスを作成し、 GetDynamicNodeCollectionメソッドを再定義すると、データがデータベースから取得されます。
public class StoreDynamicNodeProvider : DynamicNodeProviderBase { public MusicStoreEntities _db = new MusicStoreEntities(); public override IEnumerable<DynamicNode> GetDynamicNodeCollection() { var nodes = new List<DynamicNode>(); var items = _db.Genres.ToList(); foreach (var item in items) { DynamicNode node = new DynamicNode(); // node.Key = "store_" + item.GenreId.ToString(); node.RouteValues.Add("genre", item.Name); node.Action = "Browse"; node.Controller = "Store"; node.Title = item.Name; nodes.Add(node); if (item.Albums!=null) { foreach (var item2 in item.Albums) { DynamicNode node2 = new DynamicNode(); node2.Key = "album_" + item2.AlbumId.ToString(); node2.ParentKey = node.Key; node2.RouteValues.Add("id", item2.AlbumId); node2.Action = "Details"; node2.Controller = "Store"; node2.Title = item2.Title; nodes.Add(node2); } } } return nodes; } }
次に、Mvc.sitemapのStoreノードを変更する必要があります。
<mvcSiteMapNode title="Store" controller="Store" action="Index"> <mvcSiteMapNode title="" controller="Store" action="Index" dynamicNodeProvider="MvcMusicStore.Infrastructure.StoreDynamicNodeProvider, MvcMusicStore"/> </mvcSiteMapNode>
ここでの主な変更点は、動的ノードのジェネレータクラスへのフルパスを示すdynamicNodeProvider属性の追加です。
パンくずリストをWebサイトテンプレートとメニューレンダリングに追加する
ファイルViews / Shared / _Layout.cshtmlに以下を追加します。
<div style="text-align: center;"> : @Html.MvcSiteMap().SiteMapPath() </div> @Html.MvcSiteMap().Menu(2, 1)
次に、左側のメニューでアクティブなアイテムを選択します。このために、テンプレートビュー/共有/ DisplayTemplates / MenuHelperModel.cshtmlを変更する必要があります
<ul id="menu"> @foreach (var node in Model.Nodes) { <li style="@(node.IsInCurrentPath && !node.IsRootNode ? "text-decoration: underline;" : "")"> <a href="@node.Url">@node.Title</a> </li> } </ul>
次のようなものが得られます。
管理パネルに進みます。
管理パネルでは、サイト上のパスのみを表示したいのですが、左側のメニューは表示しません。
構造は次のとおりです。
- 管理者
- Facelift Albumの編集
- Facelift Albumを見る
- Facelift Albumを削除
- そして各アルバムについて
同様に、Storeセクションについて、DynamicNodeProviderBaseから継承したクラスを追加します。
public class AdminDynamicNodeProvider : DynamicNodeProviderBase { public MusicStoreEntities _db = new MusicStoreEntities(); public override IEnumerable<DynamicNode> GetDynamicNodeCollection() { var nodes = new List<DynamicNode>(); var items = _db.Albums.ToList(); foreach (var item in items) { var node=new DynamicNode() { Key="admin_album_edit_"+ item.AlbumId.ToString(), Action="Edit", Controller="StoreManager", Title=" "+item.Title }; node.RouteValues.Add("id", item.AlbumId); nodes.Add(node); node = new DynamicNode() { Key = "admin_album_delete_" + item.AlbumId.ToString(), Action = "Delete", Controller = "StoreManager", Title = " " + item.Title }; node.RouteValues.Add("id", item.AlbumId); nodes.Add(node); node = new DynamicNode() { Key = "admin_album_details_" + item.AlbumId.ToString(), Action = "Details", Controller = "StoreManager", Title = " " + item.Title }; node.RouteValues.Add("id", item.AlbumId); nodes.Add(node); } return nodes; } }
同様に、管理ノードを変更します。
<mvcSiteMapNode title="Admin" controller="StoreManager" action="Index" > <mvcSiteMapNode title="" controller="StoreManager" action="Index" dynamicNodeProvider="MvcMusicStore.Infrastructure.AdminDynamicNodeProvider, MvcMusicStore"/> <mvcSiteMapNode title="Create" controller="StoreManager" action="Create" /> </mvcSiteMapNode>
次のようになります。
メニュー内の不要なアイテムをすべて非表示にする必要がありますが、サイト上のパスは正しく表示されるはずです。 これを行うには、Mvc.sitemap必要nodahの追加属性の可視性=«SiteMapPathHelper ,! *» 、そして、それを作るために仕事が«MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider、MvcSiteMapProvider»への付加価値Mvc.sitemap変更siteMapNodeVisibilityProvider属性セクションでweb.configファイルに重要です 。
Mvc.sitemapファイルの最終バージョン:
<?xml version="1.0" encoding="utf-8" ?> <mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0 MvcSiteMapSchema.xsd" enableLocalization="true"> <mvcSiteMapNode title="Home" controller="Home" action="Index" visibility=""> <mvcSiteMapNode title="Store" controller="Store" action="Index"> <mvcSiteMapNode title="" controller="Store" action="Index" dynamicNodeProvider="MvcMusicStore.Infrastructure.StoreDynamicNodeProvider, MvcMusicStore"/> </mvcSiteMapNode> <mvcSiteMapNode title="Cart" controller="ShoppingCart" action="Index" /> <mvcSiteMapNode title="Admin" controller="StoreManager" action="Index" > <mvcSiteMapNode title="" controller="StoreManager" action="Index" visibility="SiteMapPathHelper,!*" dynamicNodeProvider="MvcMusicStore.Infrastructure.AdminDynamicNodeProvider, MvcMusicStore"/> <mvcSiteMapNode title="Create" controller="StoreManager" visibility="SiteMapPathHelper,!*" action="Create" /> </mvcSiteMapNode> </mvcSiteMapNode> </mvcSiteMap>
これですべてが正しく表示されます:
実際、それがすべてです。
サンプルのソースコードは、 ここからダウンロードできます。