Ignia.Topics.Web.Mvc
Сборка Ignia.Topics.Web.Mvc
предоставляет реализацию OnTopic для использования с платформой ASP.NET MVC 5.x.
В основе реализации MVC лежат три ключевых компонента.
MvcTopicRoutingService
: это конкретная реализация ITopicRoutingService
, которая принимает контекстную информацию о данном запросе (в данном случае URL-адрес и данные маршрутизации), а затем использует ее для получения текущей Topic
из ITopicRepository
.TopicController
: это экземпляр контроллера по умолчанию, который можно использовать для любого пути к теме. Он автоматически проверит, что Topic
существует, не отключена ( IsDisabled
) и учитывает любые перенаправления (например, если заполнен атрибут Url
). В противном случае он вернет TopicViewResult
на основе модели представления, имени представления и типа контента.TopicViewEngine
: TopicViewEngine
вызывается каждый раз, когда запрашивается представление. Он работает совместно с TopicViewResult
для идентификации соответствующих представлений MVC на основе заранее определенных местоположений и соглашений. Они обсуждаются ниже. В комплект реализации MVC входят шесть основных контроллеров. В дополнение к основному TopicController
они включают в себя следующие вспомогательные контроллеры:
ErrorControllerBase<T>
: обеспечивает поддержку действий Error
, NotFound
и InternalServer
. Может принимать любую IPageTopicViewModel
в качестве общего аргумента; который будет использоваться в качестве модели представления.FallbackController
: используется на фабрике контроллеров в качестве запасного варианта на случай, если другие контроллеры не смогут принять запрос. Просто возвращает NotFoundResult
с заранее определенным сообщением.LayoutControllerBase<T>
: обеспечивает поддержку меню навигации путем автоматического сопоставления трех верхних уровней текущего пространства имен (например, Web
, его дочерних элементов и внуков). Может принимать любую INavigationTopicViewModel
в качестве общего аргумента; который будет использоваться в качестве модели представления для каждого сопоставленного экземпляра.RedirectController
: предоставляет одно действие Redirect
, которое можно привязать к такому маршруту, как /Topic/{ID}/
; это обеспечивает поддержку постоянных URL-адресов, независимых от GetWebPath()
.SitemapController
: предоставляет одно действие Sitemap
, которое возвращает ссылку на ITopicRepository
, что позволяет рекурсивно просматривать карту сайта по всему графу темы, включая все атрибуты.Примечание. MVC не имеет практического способа обеспечить маршрутизацию для универсальных контроллеров. Таким образом, они должны быть подклассами каждой реализации. Производному контроллеру не нужно ничего делать, кроме предоставления конкретной ссылки на общий базовый тип.
По умолчанию OnTopic сопоставляет представления на основе ContentType
текущей темы и, если доступно, View
.
Существует несколько способов установки представления. TopicViewResult
автоматически оценит представления на основе следующих местоположений. Выбирается первое представление, соответствующее допустимому имени.
?View=
параметр строки запроса (например, ?View=Accordion
)Accept
заголовки (например, Accept=application/json
); будет рассматривать сегмент после /
как возможное имя представленияView
(т. е. topic.View
)ContentType
(т. е. topic.ContentType
) Для каждого из вышеперечисленных правил сопоставления представлений TopicViewEngine
будет искать подходящее представление в следующих местах:
~/Views/{ContentType}/{View}.cshtml
~/Views/ContentTypes/{ContentType}.{View}.cshtml
~/Views/ContentTypes/{ContentType}.cshtml
~/Views/Shared/{View}.cshtml
Примечание. После поиска в каждом из этих расположений для каждого из правил сопоставления представлений управление будет передано
RazorViewEngine
, который будет выполнять поиск в стандартных расположениях по умолчанию для ASP.NET MVC.
Если topic.ContentType
имеет ContentList
, а заголовок Accept
— application/json
, то TopicViewResult
и TopicViewEngine
будут координировать поиск по следующим путям:
~/Views/ContentList/JSON.cshtml
~/Views/ContentTypes/ContentList.JSON.cshtml
~/Views/ContentTypes/JSON.cshtml
~/Views/Shared/JSON.cshtml
Если совпадение не найдено, будет выполняться поиск в следующем заголовке Accept
. В конечном итоге, если в различных правилах сопоставления представлений не найдено совпадений, поиск будет осуществляться по следующим критериям:
~/Views/ContentList/ContentList.cshtml
~/Views/ContentTypes/ContentList.ContentList.cshtml
~/Views/ContentTypes/ContentList.cshtml
~/Views/Shared/ContentList.cshtml
В файле global.asax.cs
следующие компоненты должны быть зарегистрированы в обработчике событий Application_Start
:
ControllerBuilder.Current.SetControllerFactory(new OrganizationNameControllerFactory());
ViewEngines.Engines.Insert(0, new TopicViewEngine());
Примечание. Заводское имя контроллера является произвольным и должно соответствовать соглашениям, соответствующим конкретной площадке. Ignia обычно использует
{OrganizationName}ControllerFactory
(например,IgniaControllerFactory
), но OnTopic не обязательно знать или заботиться о том, какое это имя; это между вашим приложением и ASP.NET MVC Framework.
При регистрации маршрутов с помощью RouteConfig.RegisterRoutes()
(обычно через класс RouteConfig
) зарегистрируйте маршрут для любых маршрутов OnTopic:
routes.MapRoute(
name: "WebTopics",
url: "Web/{*path}",
defaults: new { controller = "Topic", action = "Index", id = UrlParameter.Optional, rootTopic = "Web" }
);
Примечание. Поскольку OnTopic использует подстановочные имена путей, новый маршрут должен быть настроен для каждого корневого пространства имен (например,
/Web
). Хотя OnTopic можно настроить для оценки всех путей, это затрудняет делегирование управления другим контроллерам и обработчикам, когда это необходимо.
Поскольку OnTopic использует внедрение конструктора, приложение должно быть настроено в корне композиции — в случае ASP.NET MVC это означает фабрику пользовательского контроллера. Базовая структура этого может выглядеть так:
var connectionString = ConfigurationManager.ConnectionStrings["OnTopic"].ConnectionString;
var sqlTopicRepository = new SqlTopicRepository(connectionString);
var cachedTopicRepository = new CachedTopicRepository(sqlTopicRepository);
var topicViewModelLookupService = new TopicViewModelLookupService();
var topicMappingService = new TopicMappingService(cachedTopicRepository, topicViewModelLookupService);
var mvcTopicRoutingService = new MvcTopicRoutingService(
cachedTopicRepository,
requestContext.HttpContext.Request.Url,
requestContext.RouteData
);
switch (controllerType.Name) {
case nameof(TopicController):
return new TopicController(sqlTopicRepository, mvcTopicRoutingService, topicMappingService);
case default:
return base.GetControllerInstance(requestContext, controllerType);
}
Полный ссылочный шаблон, включая вспомогательные контроллеры, см. в файле OrganizationNameControllerFactory.cs
Gist.
Примечание.
TopicController
по умолчанию автоматически идентифицирует текущую тему (например, на основе URL-адреса), сопоставляет текущую тему с соответствующей моделью представления (на основе соглашенийTopicMappingService
), а затем возвращает соответствующее представление (на основе соглашений о представлении). Для большинства приложений этого достаточно. Однако если необходимы пользовательские правила сопоставления или дополнительная логика представления, разработчики могут создать подклассTopicController
.