Ignia.Topics.Web.Mvc Die Ignia.Topics.Web.Mvc -Assembly stellt eine Implementierung von OnTopic zur Verwendung mit dem ASP.NET MVC 5.x Framework bereit.
Im Zentrum der MVC-Implementierung stehen drei Schlüsselkomponenten.
MvcTopicRoutingService : Dies ist eine konkrete Implementierung des ITopicRoutingService , der Kontextinformationen zu einer bestimmten Anfrage (in diesem Fall die URL und Routing-Daten) akzeptiert und diese dann verwendet, um das aktuelle Topic aus einem ITopicRepository abzurufen.TopicController : Dies ist eine Standard-Controller-Instanz, die für jeden Themenpfad verwendet werden kann. Es überprüft automatisch, ob das Topic existiert, dass es nicht deaktiviert ist ( IsDisabled ) und berücksichtigt alle Weiterleitungen (z. B. wenn das Url Attribut ausgefüllt ist). Andernfalls wird TopicViewResult basierend auf einem Ansichtsmodell, einem Ansichtsnamen und einem Inhaltstyp zurückgegeben.TopicViewEngine : Die TopicViewEngine wird jedes Mal aufgerufen, wenn eine Ansicht angefordert wird. Es arbeitet mit TopicViewResult zusammen, um passende MVC-Ansichten basierend auf vorgegebenen Standorten und Konventionen zu identifizieren. Diese werden im Folgenden besprochen. Im Lieferumfang der MVC-Implementierung sind sechs Hauptcontroller enthalten. Dazu gehören neben dem Kern TopicController die folgenden Zusatzcontroller:
ErrorControllerBase<T> : Bietet Unterstützung für die Aktionen Error , NotFound und InternalServer . Kann jedes IPageTopicViewModel als generisches Argument akzeptieren; das als Ansichtsmodell verwendet wird.FallbackController : Wird in einer Controller Factory als Fallback verwendet, falls kein anderer Controller die Anfrage akzeptieren kann. Gibt einfach ein NotFoundResult mit einer vordefinierten Nachricht zurück.LayoutControllerBase<T> : Bietet Unterstützung für ein Navigationsmenü durch automatisches Zuordnen der obersten drei Ebenen des aktuellen Namespace (z. B. Web , seine untergeordneten Elemente und Enkelelemente). Kann jedes INavigationTopicViewModel als generisches Argument akzeptieren; das als Ansichtsmodell für jede zugeordnete Instanz verwendet wird.RedirectController : Stellt eine einzelne Redirect Aktion bereit, die an eine Route wie /Topic/{ID}/ gebunden werden kann; Dies bietet Unterstützung für permanente URLs, die unabhängig von GetWebPath() sind.SitemapController : Stellt eine einzelne Sitemap Aktion bereit, die einen Verweis auf das ITopicRepository zurückgibt und so die Rekursion einer Sitemap-Ansicht über das gesamte Themendiagramm einschließlich aller Attribute ermöglicht.Hinweis: Es gibt für MVC keine praktische Möglichkeit, Routing für generische Controller bereitzustellen. Daher müssen diese von jeder Implementierung in Unterklassen unterteilt werden. Der abgeleitete Controller muss nichts anderes tun, als einen bestimmten Typverweis auf die generische Basis bereitzustellen.
Standardmäßig gleicht OnTopic Ansichten basierend auf dem ContentType des aktuellen Themas und, falls verfügbar, View .
Es gibt mehrere Möglichkeiten, eine Ansicht festzulegen. Das TopicViewResult wertet Ansichten automatisch anhand der folgenden Speicherorte aus. Der erste, der mit einem gültigen Ansichtsnamen übereinstimmt, wird ausgewählt.
?View= Abfragezeichenfolgenparameter (z. B. ?View=Accordion )Accept Header (z. B. Accept=application/json ); behandelt das Segment nach dem / als möglichen AnsichtsnamenView (z. B. topic.View )ContentType Attribut (d. h. topic.ContentType ) Für jede der oben genannten Ansichtsübereinstimmungsregeln durchsucht die TopicViewEngine die folgenden Orte nach einer übereinstimmenden Ansicht:
~/Views/{ContentType}/{View}.cshtml~/Views/ContentTypes/{ContentType}.{View}.cshtml~/Views/ContentTypes/{ContentType}.cshtml~/Views/Shared/{View}.cshtmlHinweis: Nachdem Sie jeden dieser Speicherorte nach den View Matching-Regeln durchsucht haben, wird die Steuerung an
RazorViewEngineübergeben, der die standardmäßigen Standardspeicherorte nach ASP.NET MVC durchsucht.
Wenn topic.ContentType ContentList und der Accept Header application/json ist, würden TopicViewResult und TopicViewEngine koordinieren, um die folgenden Pfade zu durchsuchen:
~/Views/ContentList/JSON.cshtml~/Views/ContentTypes/ContentList.JSON.cshtml~/Views/ContentTypes/JSON.cshtml~/Views/Shared/JSON.cshtml Wenn keine Übereinstimmung gefunden wird, wird der nächste Accept Header durchsucht. Wenn schließlich keine Übereinstimmung für die verschiedenen View-Matching-Regeln gefunden werden kann, wird nach Folgendem gesucht:
~/Views/ContentList/ContentList.cshtml~/Views/ContentTypes/ContentList.ContentList.cshtml~/Views/ContentTypes/ContentList.cshtml~/Views/Shared/ContentList.cshtml In global.asax.cs sollten die folgenden Komponenten unter dem Application_Start Ereignishandler registriert werden:
ControllerBuilder.Current.SetControllerFactory(new OrganizationNameControllerFactory());
ViewEngines.Engines.Insert(0, new TopicViewEngine());
Hinweis: Der Name der Controller-Factory ist willkürlich und sollte den für den Standort geltenden Konventionen entsprechen. Ignia verwendet normalerweise
{OrganizationName}ControllerFactory(z. B.IgniaControllerFactory), aber OnTopic muss den Namen nicht kennen oder sich darum kümmern; das ist zwischen Ihrer Anwendung und dem ASP.NET MVC Framework.
Wenn Sie Routen über RouteConfig.RegisterRoutes() registrieren (normalerweise über die RouteConfig Klasse), registrieren Sie eine Route für alle OnTopic-Routen:
routes.MapRoute(
name: "WebTopics",
url: "Web/{*path}",
defaults: new { controller = "Topic", action = "Index", id = UrlParameter.Optional, rootTopic = "Web" }
);
Hinweis: Da OnTopic auf Platzhalterpfadnamen basiert, sollte für jeden Root-Namespace (z. B.
/Web) eine neue Route konfiguriert werden. Es ist zwar möglich, OnTopic so zu konfigurieren, dass alle Pfade ausgewertet werden, dies macht es jedoch schwierig, die Kontrolle bei Bedarf an andere Controller und Handler zu delegieren.
Da OnTopic auf Konstruktorinjektion basiert, muss die Anwendung in einem Composition Root konfiguriert werden – im Fall von ASP.NET MVC bedeutet das eine benutzerdefinierte Controller-Factory. Die Grundstruktur davon könnte wie folgt aussehen:
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);
}
Eine vollständige Referenzvorlage, einschließlich der Zusatzcontroller, finden Sie im OrganizationNameControllerFactory.cs Gist.
Hinweis: Der Standard
TopicControlleridentifiziert automatisch das aktuelle Thema (z. B. basierend auf der URL), ordnet das aktuelle Thema einem entsprechenden Ansichtsmodell zu (basierend auf denTopicMappingServiceKonventionen) und gibt dann eine entsprechende Ansicht zurück (basierend auf den Ansichtskonventionen). Für die meisten Anwendungen ist dies ausreichend. Wenn jedoch benutzerdefinierte Zuordnungsregeln oder zusätzliche Präsentationslogik erforderlich sind, können Implementierer eine UnterklasseTopicControllererstellen.