html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Практическое использование MvcSiteMapProvider в ASP.net MVC tutorial recovery mode

Практическое использование MvcSiteMapProvider в ASP.net MVC

В данной статье показано использование MvcSiteMapProvider для построения динамического меню, как с его помощью сделать карту сайта и «breadcrumbs».

Практику использвания MvcSiteMapProvider я буду показывать на учебном проекте MVC Music Store.

Структура сайта следующая
Home
Store
   Rock
      The Best Of Men At Work The Best Of Men At Work
      For Those About To Rock We Salute You
   Classical
   Jazz
   …
Admin

Исходники MvcSiteMapProvider лежат на Github, лицензия MS-PL License.
Установка в проект с помощью nuget (Вид->Другие окна->Консоль диспетчера пакетов)
PM>Install-Package MvcSiteMapProvider

После установки этого пакета в папке Views/Shared/DisplayTemplates появятся новые view.

Не нужные *.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>

Xml-элемент mvcSiteMapNode — основной элемент карты сайта. Его основные атрибуты:
  • title — имя элемента, отображается в браузере
  • controller — контролёр, из маршрута
  • action — экшн, из маршрута
  • area — область (area), из маршрута
  • dynamicNodeProvider — класс, который генерирует набор mvcSiteMap, вместо этой ноды
  • visibility — видимость ноды, только карта сайта или только меню или другие варианты

Я добавил в него ноды соответствующие структуре сайта:
<?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 основных страницы. Теперь необходимо добавить жанры и альбомы в карту сайта:
  • Rock
    • The Best Of Men At Work The Best Of Men At Work
    • For Those About To Rock We Salute You
    • ...

  • Classical
  • Jazz
  • ...

Т.к. сайт у нас динамический, то альбомы и жанры будут постоянно меняться и статичная карта сайта не подойдёт. Для решения этой проблемы в 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, в котором указывается полный путь к классу-генератору динамических нод.

Добавим breadcrumbs в шаблон сайта и отрисовку меню
В файл Views/Shared/_Layout.cshtml добавим:
    <div style="text-align: center;">
        Вы здесь: @Html.MvcSiteMap().SiteMapPath()
    </div>
    @Html.MvcSiteMap().Menu(2, 1)


Теперь сделаем выделение активного пункта в левом меню, для этого надо изменить шаблон Views/Shared/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>

Получится примерно следующее:


Переходим к админке.
В админке я хочу, чтобы отображался только путь на сайте, а меню слева — нет.
Структура следующая:
  • Admin
    • Редактирование альбома Facelift
    • Просмотр альбома Facelift
    • Удаление альбома Facelift
    • и так для каждого альбома



Аналогично для раздела 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;
        }
    }


Аналогично изменим ноду Admin:
<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 в необходимых нодах добавляем атрибут visibility=«SiteMapPathHelper,!*», а чтобы он заработал важно в web.config в разделе где добавляется Mvc.sitemap поменять значение атрибута siteMapNodeVisibilityProvider на «MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider».
Окончательная версия файла 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>


Теперь всё отображается корректно:


Вот, собственно, и всё.
Исходные коды примера можно скачать здесь
Читать дальше
Twitter
Одноклассники
Мой Мир

материал с habrahabr.ru

0

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • habrahabr.ru
          • домен habrahabr.ru

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции