Ignia.Topics.Web.Mvc
Ignia.Topics.Web.Mvc
アセンブリは、ASP.NET MVC 5.x フレームワークで使用する OnTopic の実装を提供します。
MVC 実装の中心には 3 つの重要なコンポーネントがあります。
MvcTopicRoutingService
: これは、特定のリクエストに関するコンテキスト情報 (この場合は URL とルーティング データ) を受け入れ、それを使用してITopicRepository
から現在のTopic
を取得するITopicRoutingService
の具体的な実装です。TopicController
: これは、任意のトピック パスに使用できるデフォルトのコントローラー インスタンスです。 Topic
存在すること、無効になっていないこと ( IsDisabled
) が自動的に検証され、あらゆるリダイレクトが受け入れられます (たとえば、 Url
属性が入力されている場合)。それ以外の場合は、ビュー モデル、ビュー名、およびコンテンツ タイプに基づいてTopicViewResult
返します。TopicViewEngine
: TopicViewEngine
ビューが要求されるたびに呼び出されます。 TopicViewResult
と連携して、事前に決定された場所と規則に基づいて一致する MVC ビューを識別します。これらについては以下で説明します。 MVC 実装に同梱されているメイン コントローラーは 6 つあります。これらには、コアとなるTopicController
に加えて、次の補助コントローラが含まれます。
ErrorControllerBase<T>
: Error
、 NotFound
、およびInternalServer
アクションのサポートを提供します。任意のIPageTopicViewModel
汎用引数として受け入れることができます。それがビューモデルとして使用されます。FallbackController
: 他のコントローラーがリクエストを受け入れられない場合に備えて、コントローラー ファクトリでフォールバックとして使用されます。事前定義されたメッセージを含むNotFoundResult
返すだけです。LayoutControllerBase<T>
: 現在の名前空間の上位 3 層 ( Web
、その子、孫など) を自動的にマッピングすることにより、ナビゲーション メニューのサポートを提供します。任意のINavigationTopicViewModel
汎用引数として受け入れることができます。これは、マップされた各インスタンスのビュー モデルとして使用されます。RedirectController
: /Topic/{ID}/
などのルートにバインドできる単一のRedirect
アクションを提供します。これにより、 GetWebPath()
から独立した永続的な URL がサポートされます。SitemapController
: ITopicRepository
への参照を返す単一のSitemap
アクションを提供します。これにより、サイトマップ ビューがすべての属性を含むトピック グラフ全体にわたって再帰的に表示されるようになります。注: 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 フレームワークの間にあります。
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
サブクラス化できます。