6

この質問に非常によく似たものを、いくつかの機能強化を加えて実現したいと思います。

ASP.NETMVCWebアプリケーションがあります。

私は実体の木を持っています。
たとえば、PageタイプがであるChildrenというプロパティを持つクラスIList<Page>Page(クラスのインスタンスは、データベースの行に対応します。)

サイトの所有者はいつでも新しいページを追加したり、既存のページを削除したりできます。URLにはそれらの変更も反映されている必要があります。

データベース内のすべてに一意のURLを割り当てたいと思いPageます。と呼ばれるコントローラーでオブジェクト
を処理します。PagePageController

URLの例:

http://mysite.com/Page1/
http://mysite.com/Page1/SubPage/
http://mysite.com/Page/ChildPage/GrandChildPage/

あなたは絵を手に入れます。したがって、すべてのオブジェクトに、親のURLに独自の名前を加えたものに等しい独自のURLを持たせ
たいと思います。 それに加えて、シングルを(ルート)URLにマップする機能も必要です。Page
Page/

これらのルールを適用したいと思います。

  1. URLを他のルートで処理できる場合、またはファイルシステムに指定されたURLでファイルが存在する場合は、デフォルトのURLマッピングを実行します。
  2. URLを仮想パスプロバイダーで処理できる場合は、それを処理させます
  3. 他にない場合は、他のURLをPageControllerクラスにマップします

私もこの質問、そしてこれこれも見つけましたが、最初の2つのポイントについて説明していないので、あまり役に立ちませんでした。

私は次の可能な解決策を見ます:

  • 各ページのルートを個別にマッピングします。
    これには、アプリケーションの起動時にツリー全体を調べ、完全一致ルートをルートテーブルの最後に追加する必要があります。
  • ルートを追加してそれを処理{*path}するカスタムIRouteHandlerを作成することはできますが、このハンドラーがすべてを処理するため、最初の2つのルールをどのように処理できるかわかりません。

これまでのところ、最初の解決策は最も単純であるため、正しい解決策のようです。PageControllerしかし、それでも、その場合でも、リクエストを処理する方法がわかりません。

よろしくお願いします。

前もって感謝します!

編集:私は今、私が受け取ったすべての答えのすべての側面を調べる時間がありました。私はニールの答えを受け入れました。彼は物事がどのように機能するかについて最も良い説明を提供する人だからです。他のすべての回答も良いアイデアを提供するので、私は賛成しました。

4

4 に答える 4

3

ルートは、コレクションに追加された順序で処理されます。既存のルートの後にカスタムルートを追加して、それがリクエストを処理する機会を得る最後のルートであることを確認できます。これにより、既存のファイル(仮想またはその他)のルートをその前に追加できるため、基準1および2を満たすことができます。

デフォルトでは、MVCルーティングは、ルートコレクションに保存されているルートを適用する前に既存のファイルにルーティングします。http://msdn.microsoft.com/en-us/library/system.web.routing.routecollection.routeexistingfiles.aspxを参照してください。(ポールへの脱帽-コメントを参照)。

リクエストをページコントローラにルーティングするには、仮想パスを調べるカスタムルートを作成するだけで、データベース内のページのパターンと一致する場合はを返しますRouteData。仮想パスから抽出された適切な値を使用して設定しRouteData(たとえば、Pathキーを/ Parent / Child / Grandchildに設定)、コントローラーキーをページコントローラー名(たとえば、Page)に設定し、アクションをアクションの名前に設定します。実行したい(例:表示)。はでRouteData作成する必要がありますMvcRouteHandler(それが正しいクラス名であるかどうかはわかりません)。

データベース駆動型ページへのURLが正しく返されるようにするには、GetVirtualPath( RequestContext, RouteValueDictionary )メソッドをオーバーライドし、RouteBase渡されたルート値を使用して、これがデータベース駆動型ページであるかどうか、および必要な仮想パスデータを作成するかどうかを判断します(またはnullを返す場合)。

GetRouteDataとのオーバーライドについてGetVirtualPathは、との反映されたソースコードを参照してSystem.Web.Routing.RouteBaseくださいSystem.Web.Routing.Route。その後、Googleはあなたの友達です。

ルートは、コントローラー、アクション、およびその他のルート値を指定してURLを決定するために逆に使用されます。これを利用して、要求されているコンテキスト内でページのURLを作成できるはずです。

于 2010-05-31T01:41:07.727 に答える
1

"Page/{*path}"パターンを使用できます。次に、「/」で文字列を分割してパスを分解し、それをウォークするか、[生成された]パスをDBに格納して直接ルックアップするというRaroušの提案を使用できます。

Raroušの方法を使用する場合、親パスが変更されたときに、すべての子のテーブル内のパスエントリを更新する必要があります。これは、1回の更新クエリで簡単に実行できます。

ホームページに使用するページを構成ファイルまたはテーブルエントリのどこかにマッピングしていると想定しています。ホームページコントローラにルックアップを実行させ、ホームページビューのコンテンツを返してレンダリングするか(共有ビュー、部分ビューを使用するか、動作を複製しないようにページコントローラを呼び出すことができます)、またはそのページにリダイレクトさせることができます。

この手法を使用すると、これらすべてのページを同じ方法で処理する単一のページコントローラーとビューを作成できます。他の要件は、MVCフレームワークによって自動的に処理されるようです。

パスは次のようになります。

http://mysite.com/Page/Page1/ 
http://mysite.com/Page/Page1/SubPage/ 
http://mysite.com/Page/Page/ChildPage/GrandChildPage/ 

もちろん、「ページ」以外のプレフィックスを使用することもできます。

于 2010-06-07T10:10:48.587 に答える
1

T4 (Text Template Transformation Toolkit) を使用して Children を一度読み取り、Global.asax ファイルのコンテンツを生成するという別のアイデアもあります。

編集: 基本的に T4 を使用すると、テキスト ファイルの生成を自動化できます。たとえば、巨大なコレクションのアイテムを手動でコピーして、特定のコンテキストとともにテキスト ファイル ( などINSERT INTO [MyTable] (Text) VALUES (@ItemText)) に貼り付ける代わりに、T4 エンジンにコレクションを読み取らせて、これらの挿入ステートメントを生成させることができます。これは静的であり、ランタイム向けではありません。

Pro Entity Framework 4.0の本から非常に良い紹介が得られることがわかりました。

しかし、動的に行う必要があると言う場合、これはあなたのためのツールではないかもしれません.

于 2010-05-23T10:40:31.563 に答える
1

ページを保存すると、ページの構造がわかります。したがって、各ページの URL を生成し、データベース レコードに保存できます。{*path}次に、ルールを使用して、データベースで完全一致を見つけることができます。このルールは、ルール定義の最後にある必要があるため、他のルートと一致させることができます。

たとえば、あなたPage1には親ページがなく、その URL はPage1. あなたはそれが親であることを知っているので、URLなどSubPageをガナレートできます.Page1/SubPage

于 2010-06-05T14:25:55.497 に答える