Ignia.Topics.Web.Mvc Ignia.Topics.Web.Mvc組件提供了與 ASP.NET MVC 5.x Framework 一起使用的 OnTopic 實作。
MVC 實作的核心包含三個關鍵元件。
MvcTopicRoutingService :這是ITopicRoutingService的具體實現,它接受有關給定請求的上下文資訊(在本例中為 URL 和路由資料),然後使用它從ITopicRepository檢索當前Topic 。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}/ ;這為獨立於GetWebPath()的永久 URL 提供支援。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 header 是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 框架之間。
透過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。