Ignia.Topics.Web.Mvc
L'assembly Ignia.Topics.Web.Mvc
fournit une implémentation d'OnTopic à utiliser avec le framework ASP.NET MVC 5.x.
Il y a trois composants clés au cœur de la mise en œuvre de MVC.
MvcTopicRoutingService
: Il s'agit d'une implémentation concrète de ITopicRoutingService
qui accepte des informations contextuelles sur une requête donnée (dans ce cas, l'URL et les données de routage) et les utilise ensuite pour récupérer le Topic
actuel à partir d'un ITopicRepository
.TopicController
: Il s'agit d'une instance de contrôleur par défaut qui peut être utilisée pour n'importe quel chemin de rubrique. Il validera automatiquement que le Topic
existe, qu'il n'est pas désactivé ( IsDisabled
), et honorera toutes les redirections (par exemple, si l'attribut Url
est renseigné). Sinon, il renverra TopicViewResult
en fonction d'un modèle de vue, d'un nom de vue et d'un type de contenu.TopicViewEngine
: Le TopicViewEngine
est appelé à chaque fois qu'une vue est demandée. Il fonctionne conjointement avec TopicViewResult
pour identifier les vues MVC correspondantes en fonction d'emplacements et de conventions prédéterminés. Ceux-ci sont discutés ci-dessous. Six contrôleurs principaux sont fournis avec l'implémentation MVC. En plus du TopicController
principal, ceux-ci incluent les contrôleurs auxiliaires suivants :
ErrorControllerBase<T>
: fournit la prise en charge des actions Error
, NotFound
et InternalServer
. Peut accepter n’importe quel IPageTopicViewModel
comme argument générique ; qui sera utilisé comme modèle de vue.FallbackController
: utilisé dans une Controller Factory comme solution de secours, au cas où aucun autre contrôleur ne pourrait accepter la demande. Renvoie simplement un NotFoundResult
avec un message prédéfini.LayoutControllerBase<T>
: Fournit la prise en charge d'un menu de navigation en mappant automatiquement les trois premiers niveaux de l'espace de noms actuel (par exemple, Web
, ses enfants et petits-enfants). Peut accepter n’importe quel INavigationTopicViewModel
comme argument générique ; qui sera utilisé comme modèle de vue pour chaque instance mappée.RedirectController
: Fournit une seule action Redirect
qui peut être liée à une route telle que /Topic/{ID}/
; cela prend en charge les URL permanentes indépendantes de GetWebPath()
.SitemapController
: fournit une seule action Sitemap
qui renvoie une référence au ITopicRepository
, permettant ainsi à une vue de plan de site de se répéter sur l'ensemble du graphique du sujet, y compris tous les attributs.Remarque : Il n'existe aucun moyen pratique pour MVC de fournir un routage pour les contrôleurs génériques. En tant que tels, ceux-ci doivent être sous-classés par chaque implémentation. Le contrôleur dérivé n'a pas besoin de faire autre chose que de fournir une référence de type spécifique à la base générique.
Par défaut, OnTopic fait correspondre les vues en fonction du ContentType
du sujet actuel et, si disponible, View
.
Il existe plusieurs façons de définir une vue. Le TopicViewResult
évaluera automatiquement les vues en fonction des emplacements suivants. Le premier qui correspond à un nom de vue valide est sélectionné.
?View=
paramètre de chaîne de requête (par exemple, ?View=Accordion
)Accept
les en-têtes (par exemple, Accept=application/json
); traitera le segment après le /
comme nom de vue possibleView
(c'est-à-dire topic.View
)ContentType
(c'est-à-dire topic.ContentType
) Pour chacune des règles de correspondance de vue ci-dessus, TopicViewEngine
recherchera une vue correspondante aux emplacements suivants :
~/Views/{ContentType}/{View}.cshtml
~/Views/ContentTypes/{ContentType}.{View}.cshtml
~/Views/ContentTypes/{ContentType}.cshtml
~/Views/Shared/{View}.cshtml
Remarque : Après avoir recherché chacun de ces emplacements pour chacune des règles de correspondance de vue, le contrôle sera transféré à
RazorViewEngine
, qui recherchera les emplacements par défaut prêts à l'emploi pour ASP.NET MVC.
Si le topic.ContentType
est ContentList
et que l'en-tête Accept
est application/json
, TopicViewResult
et TopicViewEngine
se coordonneront pour rechercher les chemins suivants :
~/Views/ContentList/JSON.cshtml
~/Views/ContentTypes/ContentList.JSON.cshtml
~/Views/ContentTypes/JSON.cshtml
~/Views/Shared/JSON.cshtml
Si aucune correspondance n’est trouvée, l’en-tête Accept
suivant sera recherché. Finalement, si aucune correspondance ne peut être trouvée sur les différentes règles de correspondance de vue, alors les éléments suivants seront recherchés :
~/Views/ContentList/ContentList.cshtml
~/Views/ContentTypes/ContentList.ContentList.cshtml
~/Views/ContentTypes/ContentList.cshtml
~/Views/Shared/ContentList.cshtml
Dans global.asax.cs
, les composants suivants doivent être enregistrés sous le gestionnaire d'événements Application_Start
:
ControllerBuilder.Current.SetControllerFactory(new OrganizationNameControllerFactory());
ViewEngines.Engines.Insert(0, new TopicViewEngine());
Remarque : Le nom de la fabrique du contrôleur est arbitraire et doit suivre les conventions appropriées au site. Ignia utilise généralement
{OrganizationName}ControllerFactory
(par exemple,IgniaControllerFactory
), mais OnTopic n'a pas besoin de connaître le nom ni de se soucier de son nom ; c'est entre votre application et le framework ASP.NET MVC.
Lors de l'enregistrement de routes via RouteConfig.RegisterRoutes()
(généralement via la classe RouteConfig
), enregistrez une route pour toutes les routes OnTopic :
routes.MapRoute(
name: "WebTopics",
url: "Web/{*path}",
defaults: new { controller = "Topic", action = "Index", id = UrlParameter.Optional, rootTopic = "Web" }
);
Remarque : étant donné qu'OnTopic s'appuie sur des noms de chemin génériques, une nouvelle route doit être configurée pour chaque espace de noms racine (par exemple,
/Web
). Bien qu'il soit possible de configurer OnTopic pour évaluer tous les chemins, cela rend difficile la délégation du contrôle à d'autres contrôleurs et gestionnaires, lorsque cela est nécessaire.
Comme OnTopic repose sur l'injection de constructeur, l'application doit être configurée dans une racine de composition — dans le cas d'ASP.NET MVC, cela signifie une fabrique de contrôleurs personnalisée. La structure de base de ceci pourrait ressembler à :
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);
}
Pour un modèle de référence complet, y compris les contrôleurs auxiliaires, consultez l'essentiel de OrganizationNameControllerFactory.cs
.
Remarque : Le
TopicController
par défaut identifiera automatiquement le sujet actuel (en fonction, par exemple, de l'URL), mappera le sujet actuel à un modèle de vue correspondant (basé sur les conventionsTopicMappingService
), puis renverra une vue correspondante (basée sur les conventions de vue). Pour la plupart des applications, cela suffit. Si des règles de mappage personnalisées ou une logique de présentation supplémentaire sont nécessaires, les implémenteurs peuvent toutefois sous-classerTopicController
.