Pull to refresh

ASP.NET: расширяем механизм путей SiteMapPath

Reading time3 min
Views2.1K
При разработке на ASP.NET мы привыкли для стандартных задач использовать стандартные компоненты. Одной из таких стандартных задач является вывод на каждой странице сайта пути к ней от главной страницы — фрагмента карты сайта (sitemap path). Для этого используется контрол SiteMapPath, берущий данные о карте сайта от провайдера карты сайта (SiteMapProvider) по умолчанию, который, в свою очередь, берет их из конфигурационного файла Web.siteMap.

Поместив этот контрол на мастер-страницу сайта, и описав в конфигурационном файле карту сайта, мы тем самым обеспечиваем вывод пути на всех страницах.

Но ASP.NET — расширяемая среда, и позволяет замещать почти все стандартные модули, и провайдер карт сайта — не исключение. Мы рассмотрим, как создать свой провайдер для получения расширенной функциональности для карты сайта.


Стандартный компонент SiteMapPath, показывающий на странице текущее положение пользователя на сайте, ограничен тем, что ссылки, выводимые им, являются статическим текстом, берущимся из конфигурационного файла web.sitemap. Таким образом, вывести на странице путь «Альбомы >> Просмотр альбома >> Просмотр фотографии» можно с его помощью, а вот подставить туда динамические данные, например «Альбомы >> Поездка в Крым 2007 >> Вова прыгает с пирса» уже нельзя.

Вообще и написать свой аналогичный контрол, выводящий «то, что скажут» — дело недолгое, но интересно заставить сделать это стандартный SiteMapPath.

Для этого необходимо реализовать свой вариант класса SiteMapProvider.

Для постановки задачи рассмотрим классический пример фрагмента sitemap-файла:

sitemap 1

Имея такой sitemap, мы на странице описания iPhone увидим такой путь: «Каталог >> Описание товара». Но было бы интереснее, если бы он выглядел как «Каталог >> Описание iPhone». Интуитивно это предполагает наличие какого-то такого siteMap:

sitemap 2

Но если представить, что для описания товара есть еще более логически вложенные страницы, например, существует «Каталог >> Описание iPhone >> Фотографии», то пользователь, перейдя в раздел «Фотографии», может нажать на «Описание iPhone», чтобы вернуться к предыдущей странице. Становится ясным, что необходима еще и корректность ссылки «Описание iPhone», которая пока что у нас выглядит как url=«good.aspx», т.е. не указывает на какой-либо конкретный товар. Таким образом, выходит, что мы должны добавлять и в url некие динамические фрагменты, и полученный в итоге «воображаемый» siteMap выглядит так:

site map final

Итак, задача выглядит так: написать SiteMapProvider, поддерживающий расширенный синтаксис siteMap, приведенный выше, чтобы выводить динамическое содержимое в SiteMapPath.

Интересным вопросом ещё является то, откуда брать эту самую контекстную динамическую информацию. В реалиях моей работы, на странице обычно есть свойство, представляющее бизнес-объект, который она показывает. Например, на странице Good.aspx есть свойство Good типа Good, представляющее показываемый её объект Товар. Поэтому удобно, чтобы содержимое фрагмента метаподстановки ([$...$]) интерпретировалось как путь свойств, тогда выражения вида Good.ID и Good.Name — обращения к свойствам ID и Name бизнес-сущности, представленной через свойство Good текущей страницы (good.aspx).

В вашем случае может быть удобно брать эти данные из других источников или другими методами — это легко реализовать, метаподстановка будет хорошо локализована в коде нашего разрабатываемого класса.

Для реализации своего провайдера удобно отнаследоваться от стандартного SiteMapProvider и переопределить ряд свойств и методов. Дабы не утомлять читателя техническими подробностями, приведу код полученного класса в вложении.


 Файл с кодом провайдера: DynamicXmlSiteMapProvider.cs
Надеюсь, кому-нибудь пригодится :-)


Кросс-пост из блога компании Gendix
Tags:
Hubs:
+1
Comments6

Articles