ASP.NET での URL の書き換え

 

Scott Mitchell
4GuysFromRolla.com

2004 年 3 月

適用対象:
   Microsoft® ASP.NET

概要: Microsoft ASP.NET で動的 URL の書き換えを実行する方法について説明します。 URL の書き換えは、受信 Web 要求をインターセプトし、それを別の URL に自動的にリダイレクトするプロセスです。 URL 書き換えを実装するためのさまざまな手法について説明し、URL の書き換えの実際のシナリオについて説明します。 (31ページ印刷)

この記事のソース コードをダウンロードします

内容

はじめに
URL 書き換えの一般的な用途
要求が IIS に到達した場合の動作
URL 書き換えの実装
URL 書き換えエンジンの構築
URL 書き換えエンジンを使用した単純な URL 書き換えの実行
真に "ハッキング可能" な URL の作成
まとめ
関連書籍

はじめに

少し時間を取って、Web サイトの一部の URL を確認してください。 type=summary のようなhttp://yoursite.com/info/dispEmployeeInfo.aspx?EmpID=459-099\& URL は見つかりますか? または、あるディレクトリまたは Web サイトから別のディレクトリまたは Web サイトに移動された多数の Web ページがあり、古い URL をブックマークした訪問者のリンクが壊れている可能性があります。 この記事では、URL の書き換えを使用して、これらの醜い URL を意味のある思い出深いものに短縮する方法について説明します。type=summary は のようなものに置き換えますhttp://yoursite.com/info/dispEmployeeInfo.aspx?EmpID=459-099\&http://yoursite.com/people/sales/chuck.smith また、URL の書き換えを使用してインテリジェントな 404 エラーを作成する方法についても説明します。

URL の書き換えは、受信 Web 要求をインターセプトし、要求を別のリソースにリダイレクトするプロセスです。 URL の書き換えを実行する場合、通常は要求される URL がチェックされ、その値に基づいて、要求は別の URL にリダイレクトされます。 たとえば、Web サイトの再構築によって /people/ ディレクトリ内のすべての Web ページが /info/employees/ ディレクトリに移動された場合、Web 要求が /people/ ディレクトリ内のファイルを対象としている場合は、url を チェック に書き換えます。 要求が /people/ ディレクトリ内のファイルの場合は、要求を同じファイルに自動的にリダイレクトしますが、代わりに /info/employees/ ディレクトリにリダイレクトします。

従来の ASP では、URL 書き換えを利用する唯一の方法は、ISAPI フィルターを記述するか、URL 書き換え機能を提供するサードパーティ製品を購入することでした。 ただし、Microsoft® ASP.NET では、さまざまな方法で独自の URL 書き換えソフトウェアを簡単に作成できます。 この記事では、URL の書き換えを実装するために ASP.NET 開発者が利用できる手法を調べてから、URL の書き換えのいくつかの実際の使用方法に目を向けます。 URL 書き換えの技術的な詳細を調べる前に、まず、URL の書き換えを使用できる日常的なシナリオを見てみましょう。

URL 書き換えの一般的な用途

データ ドリブン ASP.NET Web サイトを作成すると、多くの場合、クエリ文字列パラメーターに基づいてデータベースのデータのサブセットを表示する単一の Web ページが作成されます。 たとえば、eコマース サイトを設計する場合、タスクの 1 つは、ユーザーが販売する製品を閲覧できるようにすることです。 これを容易にするために、特定のカテゴリの製品を表示する displayCategory.aspx というページを作成できます。 表示するカテゴリの製品は、querystring パラメーターによって指定されます。 つまり、ユーザーが販売のためにウィジェットを参照し、すべてのウィジェットの CategoryID が 5 の場合、ユーザーは にアクセスします http://yousite.com/displayCategory.aspx?CategoryID=5

このような URL を使用して Web サイトを作成するには、2 つの欠点があります。 まず、エンド ユーザーの観点から見ると、URL http://yousite.com/displayCategory.aspx?CategoryID=5 は混乱しています。 使いやすさの専門家である Jakob Neilsen は、次のように URL を選択することをお勧めします

  • 短い。
  • 入力が簡単です。
  • サイト構造を視覚化します。
  • "Hackable" を使用すると、ユーザーは URL の一部をハッキングしてサイト内を移動できます。

そのリストに、URL も覚えやすいものに追加します。 URL http://yousite.com/displayCategory.aspx?CategoryID=5 は Neilsen の条件を満たしていないので、覚えやすいものもありません。 ユーザーにクエリ文字列値の入力を求めることにより、URL の入力が困難になり、クエリ文字列パラメーターの目的とその名前と値のペア構造を理解している経験豊富な Web 開発者のみが URL を "ハッキング可能" にします。

より良い方法は、 などの http://yoursite.com/products/Widgetsわかりやすい思い出深い URL を許可することです。 URL を見るだけで、表示されるウィジェットに関する情報を推測できます。 URL は覚えやすく、共有も簡単です。 私は同僚に「yoursite.com/products/Widgets チェックアウト」と言うことができ、URLが何だったのかもう一度尋ねることなくページを表示できる可能性があります。 (たとえば、Amazon.com ページで行ってみてください。URL も表示され、"hackable" と動作します。つまり、ユーザーが URL の末尾をハッキングし、 で http://yoursite.com/products型を入力すると、 すべての 製品の一覧、または表示できる製品のすべてのカテゴリの少なくとも一覧が表示されます。

メモ "hackable" URL の主な例として、多くのブログ エンジンによって生成される URL を考えてみましょう。 2004 年 1 月 28 日の投稿を表示するには、 のような http://someblog.com/2004/01/28URL にアクセスします。 URL が に http://someblog.com/2004/01ハッキングされた場合、ユーザーには 2004 年 1 月のすべての投稿が表示されます。 さらに減らすと http://someblog.com/2004 、2004 年のすべての投稿が表示されます。

URL の簡略化に加えて、URL の書き換えは、Web サイトの再構築を処理するためによく使用されます。そうしないと、多数のリンクが壊れ、ブックマークが古くなります。

要求が IIS に到達した場合の動作

URL の書き換えを実装する方法を正確に調べる前に、Microsoft® インターネット インフォメーション サービス (IIS) によって受信要求がどのように処理されるかを理解しておくことが重要です。 IIS Web サーバーに要求が到着すると、IIS は要求されたファイルの拡張子を調べて、要求の処理方法を決定します。 要求は、HTML ページ、イメージ、およびその他の静的コンテンツと同様に、IIS によってネイティブに処理することも、IIS が要求を ISAPI 拡張機能にルーティングすることもできます。 (ISAPI 拡張機能は、受信 Web 要求を処理するアンマネージドのコンパイル済みクラスです。そのタスクは、要求されたリソースのコンテンツを生成することです)。

たとえば、Info.asp という名前の Web ページに対して要求が送信された場合、IIS はメッセージを asp.dll ISAPI 拡張機能にルーティングします。 この ISAPI 拡張機能は、要求された ASP ページを読み込んで実行し、レンダリングされた HTML を IIS に返します。これにより、要求元のクライアントに送り返されます。 ASP.NET ページの場合、IIS はメッセージを aspnet_isapi.dll ISAPI 拡張機能にルーティングします。 aspnet_isapi.dll ISAPI 拡張機能は、マネージド ASP.NET ワーカー プロセスに処理を引き受け、要求を処理し、ASP.NET Web ページのレンダリングされた HTML を返します。

IIS をカスタマイズして、ISAPI 拡張機能にマップされる拡張機能を指定できます。 図 1 は、インターネット インフォメーション サービス管理ツールの [アプリケーション構成] ダイアログ ボックスを示しています。 ASP.NET 関連の拡張機能 (.aspx、.ascx、.config、.asmx、.rem、.cs、.vb など) はすべて、aspnet_isapi.dll ISAPI 拡張機能にマップされることに注意してください。

ms972974.urlrewriting_fig01(en-us,MSDN.10).gifms972974.urlrewriting_fig01

図 1. ファイル拡張子の構成済みマッピング

IIS が受信要求を管理する方法の詳細については、この記事の範囲外です。 ただし、ミケーレ・ルルー・ブスタマンテの記事「 IIS と ASP.NET 内」で詳しく説明されています。 ASP.NET エンジンは、拡張機能が IIS 内のaspnet_isapi.dllに明示的にマップされている受信 Web 要求にのみ対応することを理解することが重要です。

ISAPI フィルターを使用した要求の確認

受信 Web 要求のファイル拡張子を適切な ISAPI 拡張子にマッピングするだけでなく、IIS は他の多くのタスクも実行します。 たとえば、IIS は要求を行うユーザーの認証を試み、認証されたユーザーが要求されたファイルにアクセスするための承認を持っているかどうかを判断します。 要求の処理の有効期間中、IIS はいくつかの状態を通過します。 各状態で、IIS は ISAPI フィルターを使用してプログラムで処理できるイベントを発生させます。

ISAPI 拡張機能と同様に、ISAPI フィルターは、Web サーバーにインストールされているアンマネージド コードのブロックです。 ISAPI 拡張機能は、特定のファイルの種類に対する要求の応答を生成するように設計されています。 一方、ISAPI フィルターには、IIS によって発生したイベントに応答するコードが含まれています。 ISAPI フィルターは、受信データと送信データをインターセプトして変更することもできます。 ISAPI フィルターには、次のような多数のアプリケーションがあります。

  • 認証と認可。
  • ログ記録と監視。
  • HTTP 圧縮。
  • URL の書き換え。

ISAPI フィルターを使用して URL の書き換えを実行できますが、この記事では、ASP.NET を使用した URL 書き換えの実装について説明します。 ただし、URL の書き換えを ISAPI フィルターとして実装することと、ASP.NET で使用できる手法を使用する場合のトレードオフについて説明します。

要求が ASP.NET エンジンに入ったときの動作

ASP.NET する前に、IIS Web サーバーの URL 書き換えを ISAPI フィルターを使用して実装する必要があります。 ASP.NET エンジンは IIS と顕著に似ているため、ASP.NET で URL の書き換えが可能です。 類似点は、ASP.NET エンジンが次の理由で発生します。

  1. 要求を処理する際にイベントを発生させます。
  2. IIS の ISAPI フィルターと同じ、発生したイベントを任意の数の HTTP モジュール が処理できるようにします。
  3. 要求されたリソースのレンダリングを、IIS の ISAPI 拡張機能と同じ HTTP ハンドラーに委任します。

IIS と同様に、要求の有効期間中に、ASP.NET エンジンは、処理の状態から別の状態への変更を通知するイベントを発生させます。 たとえば、 BeginRequest イベントは、ASP.NET エンジンが最初に要求に応答したときに発生します。 AuthenticateRequest イベントは次に発生します。これは、ユーザーの ID が確立されたときに発生します。 (AuthorizeRequest、ResolveRequestCacheEndRequest など、他にも多数 イベントがあります。これらのイベントは 、System.Web.HttpApplication クラスのイベントです。詳細については、 HttpApplication クラスの概要 に関するテクニカル ドキュメントを参照してください)。

前のセクションで説明したように、IIS によって発生したイベントに応答するために ISAPI フィルターを作成できます。 同様に、ASP.NET は、ASP.NET エンジンによって発生したイベントに応答できる HTTP モジュール を提供します。 ASP.NET Web アプリケーションは、複数の HTTP モジュールを持つよう構成できます。 ASP.NET エンジンによって処理される要求ごとに、構成された各 HTTP モジュールが初期化され、要求の処理中に発生したイベントにイベント ハンドラーを接続できます。 要求ごとに多数の組み込み HTTP モジュールが使用されていることに気付きます。 組み込みの HTTP モジュールの 1 つは FormsAuthenticationModule です。フォーム認証が使用されているかどうかを最初に確認し、使用されている場合はユーザーが認証されているかどうかを確認します。 そうでない場合、ユーザーは指定されたログオン ページに自動的にリダイレクトされます。

IIS では、着信要求は最終的に ISAPI 拡張機能に送信され、そのジョブは特定の要求のデータを返す作業であることを思い出してください。 たとえば、従来の ASP Web ページの要求が到着すると、IIS は要求を asp.dll ISAPI 拡張機能に送信します。この拡張機能は、要求された ASP ページの HTML マークアップを返すタスクです。 ASP.NET エンジンも同様のアプローチを利用します。 HTTP モジュールを初期化した後、ASP.NET エンジンの次のタスクは、要求を処理する HTTP ハンドラー を決定することです。

ASP.NET エンジンを通過するすべての要求は、最終的に HTTP ハンドラーまたは HTTP ハンドラー ファクトリに到着します (HTTP ハンドラー ファクトリは、要求の処理に使用される HTTP ハンドラーのインスタンスを返すだけです)。 最後の HTTP ハンドラーは、要求されたリソースをレンダリングし、応答を返します。 この応答は IIS に送り返され、要求を行ったユーザーに返されます。

ASP.NET には、多数の組み込み HTTP ハンドラーが含まれています。 たとえば、 PageHandlerFactory は、Web ページ ASP.NET レンダリングするために使用されます。 WebServiceHandlerFactory は、ASP.NET Web サービスの応答 SOAP エンベロープをレンダリングするために使用されます。 TraceHandler は、trace.axd への要求の HTML マークアップをレンダリングします。

図 2 は、ASP.NET リソースの要求がどのように処理されるかを示しています。 最初に、IIS は要求を受け取り、aspnet_isapi.dllにディスパッチします。 次に、ASP.NET エンジンによって、構成された HTTP モジュールが初期化されます。 最後に、適切な HTTP ハンドラーが呼び出され、要求されたリソースがレンダリングされ、生成されたマークアップが IIS に返され、要求元のクライアントに返されます。

ms972974.urlrewriting_fig02(en-us,MSDN.10).gifms972974.urlrewriting_fig02

図 2. IIS と ASP.NET による要求処理

カスタム HTTP モジュールと HTTP ハンドラーの作成と登録

カスタム HTTP モジュールと HTTP ハンドラーの作成は比較的単純なタスクであり、適切なインターフェイスを実装するマネージド クラスが作成されます。 HTTP モジュールでは System.Web.IHttpModule インターフェイスを実装する必要があります。一方、HTTP ハンドラー ファクトリと HTTP ハンドラー ファクトリは、それぞれ System.Web.IHttpHandler インターフェイスと System.Web.IHttpHandlerFactory インターフェイスを実装する必要があります。 HTTP ハンドラーと HTTP モジュールの作成の詳細については、この記事の範囲外です。 適切な背景については、Mansoor のアハメド・Siddiqui の記事「 http handlers and HTTP Modules in ASP.NET」を参照してください。

カスタム HTTP モジュールまたは HTTP ハンドラーが作成されたら、Web アプリケーションに登録する必要があります。 Web サーバー全体の HTTP モジュールと HTTP ハンドラーを登録するには、machine.config ファイルに簡単に追加するだけで済みます。特定の Web アプリケーションの HTTP モジュールまたは HTTP ハンドラーを登録するには、アプリケーションの Web.config ファイルに数行の XML を追加する必要があります。

具体的には、HTTP モジュールを Web アプリケーションに追加するには、Web.configの configuration/system.web セクションに次の行を追加します。

<httpModules>
   <add type="type" name="name" />
</httpModules>

の値は HTTP モジュールのアセンブリ名とクラス名を提供しますが、名前の値は Global.asax ファイルで HTTP モジュールを参照できるフレンドリ名を提供します。

HTTP ハンドラーと HTTP ハンドラー ファクトリは、次のように、Web.configの configuration/system.web セクションの httpHandlers> タグによって<構成されます。

<httpHandlers>
   <add verb="verb" path="path" type="type" />
</httpHandlers>

受信要求ごとに、ASP.NET エンジンが要求のレンダリングに使用する HTTP ハンドラーを決定することを思い出してください。 この決定は、受信要求の動詞とパスに基づいて行われます。 動詞は、行われた HTTP 要求の種類 (GET または POST) を指定します。一方、パスは要求されたファイルの場所とファイル名を指定します。 そのため、HTTP ハンドラーで .scott 拡張子を持つファイルのすべての要求 (GET または POST) を処理する場合は、Web.config ファイルに次を追加します。

<httpHandlers>
   <add verb="*" path="*.scott" type="type" />
</httpHandlers>

ここで、type は HTTP ハンドラーの型でした。

メモ HTTP ハンドラーを登録するときは、HTTP ハンドラーで使用される拡張機能が IIS で ASP.NET エンジンにマップされていることを確認することが重要です。 つまり、.scott の例では、.scott 拡張子が IIS で aspnet_isapi.dll ISAPI 拡張子にマップされていない場合、foo.scott ファイルに対する要求により、IIS は foo.scott ファイルの内容を返そうとします。 HTTP ハンドラーがこの要求を処理するには、.scott 拡張機能を ASP.NET エンジンにマップする必要があります。 ASP.NET エンジンは、要求を適切な HTTP ハンドラーに正しくルーティングします。

HTTP モジュールと HTTP ハンドラーの登録の詳細については、httpModules> 要素のドキュメントと httpHandlers 要素のドキュメントを参照<してください<>

URL 書き換えの実装

URL の書き換えは、IIS Web サーバー レベルの ISAPI フィルターを使用するか、ASP.NET レベルの HTTP モジュールまたは HTTP ハンドラーを使用して実装できます。 この記事では、ASP.NET を使用した URL 書き換えの実装に焦点を当てているため、ISAPI フィルターを使用した URL 書き換えの実装の詳細については説明しません。

system.Web.HttpContext クラスの RewritePath() メソッドを使用して、ASP.NET レベルで URL 書き換えを実装できます。 HttpContext クラスには、特定の HTTP 要求に関する HTTP 固有の情報が含まれています。 ASP.NET エンジンによって受信された要求ごとに、その要求に対して HttpContext インスタンスが作成されます。 このクラスには、 受信要求 と送信 応答へのアクセスを提供する Request と Response などのプロパティがあります。 アプリケーションセッション。アプリケーション変数とセッション変数へのアクセスを提供します。 ユーザー。認証されたユーザーに関する情報を提供します。およびその他の関連プロパティ。

Microsoft® .NET Framework バージョン 1.0 では、RewritePath() メソッドは、使用する新しいパスである 1 つの文字列を受け入れます。 内部的には、 HttpContext クラスの RewritePath(string) メソッドは 、Request オブジェクトの Path プロパティと QueryString プロパティを更新します。 RewritePath(string)に加えて、.NET Framework バージョン 1.1 には、3 つの文字列入力パラメーターを受け入れるもう 1 つの形式の RewritePath() メソッドが含まれています。 この代替オーバーロードされた形式は、Request オブジェクトの Path プロパティと QueryString プロパティを設定するだけでなく、PhysicalPathPathInfoおよび FilePath プロパティの Request オブジェクトの値を計算するために使用される内部メンバー変数も設定します。

ASP.NET で URL の書き換えを実装するには、次の HTTP モジュールまたは HTTP ハンドラーを作成する必要があります。

  1. 要求されたパスを確認して、URL を書き換える必要があるかどうかを判断します。
  2. 必要に応じて、 RewritePath() メソッドを呼び出してパスを書き直します。

たとえば、Web サイトに /info/employee.aspx?empID=employeeID を介してアクセスできる各従業員の情報があるとします。 URL をより "ハッキング可能" にするには、従業員ページに /people/EmployeeName.aspx でアクセスできるようにすることにしました。 URL の書き換えを使用する場合を次に示します。 つまり、ページ /people/ScottMitchell.aspx が要求されたときに、代わりにページ /info/employee.aspx?empID=1001 が使用されるように URL を書き換えます。

HTTP モジュールを使用した URL の書き換え

ASP.NET レベルで URL 書き換えを実行する場合は、HTTP モジュールまたは HTTP ハンドラーを使用して書き換えを実行できます。 HTTP モジュールを使用する場合は、要求のライフサイクル中に URL を書き換える必要があるかどうかを確認するために、チェックする時点で決定する必要があります。 一見すると、これは任意の選択のように見えるかもしれませんが、決定は重要な方法と微妙な方法の両方でアプリケーションに影響を与える可能性があります。 組み込みの ASP.NET HTTP モジュールは Request オブジェクトのプロパティを使用して作業を実行するため、書き換えを実行する場所の選択が重要です。 (パスを書き直すと 、Request オブジェクトのプロパティ値が変更されることを思い出してください。これらのドイツ語の組み込み HTTP モジュールと、それらが関連付けるイベントを次に示します。

HTTP モジュール Event 説明
FormsAuthenticationModule AuthenticateRequest ユーザーがフォーム認証を使用して認証されているかどうかを判断します。 そうでない場合、ユーザーは指定されたログオン ページに自動的にリダイレクトされます。
FileAuthorizationMoudle AuthorizeRequest Windows 認証を使用する場合、この HTTP モジュールは、要求されたリソースに対する適切な権限が Microsoft® Windows® アカウントにあることを確認します。
UrlAuthorizationModule AuthorizeRequest リクエスタが指定された URL にアクセスできることを確認します。 URL 承認は、Web.config ファイル内の <authorization> 要素と <location> 要素によって指定されます。

BeginRequest イベントは AuthenticateRequest の前に発生し、AuthorizeRequest の前に発生することを思い出してください

URL の書き換えを実行できる安全な場所の 1 つは、 BeginRequest イベントです。 つまり、URL を書き換える必要がある場合は、組み込みの HTTP モジュールが実行されるまでに行われます。 この方法の欠点は、フォーム認証を使用する場合に発生します。 以前にフォーム認証を使用したことがある場合、ユーザーが制限付きリソースにアクセスすると、指定したログイン ページに自動的にリダイレクトされることがわかります。 ログインに成功すると、ユーザーは最初にアクセスしようとしたページに送り返されます。

BeginRequest イベントまたは AuthenticateRequest イベントで URL の書き換えが実行された場合、ログイン ページは送信されると、ユーザーを書き換えられたページにリダイレクトします。 つまり、ユーザーがブラウザー ウィンドウ /people/ScottMitchell.aspx を入力すると、/info/employee.aspx?empID=1001 に書き換えられます。 フォーム認証を使用するように Web アプリケーションが構成されている場合、ユーザーが最初に /people/ScottMitchell.aspx にアクセスすると、最初に URL が /info/employee.aspx?empID=1001 に書き換えられます。次に、 FormsAuthenticationModule が実行され、必要に応じてユーザーがログイン ページにリダイレクトされます。 ただし、ユーザーが正常にログインしたときに送信される URL は/info/employee.aspx?empID=1001 になります。これは、 FormsAuthenticationModule が実行されたときの要求の URL であるためです。

同様に、 BeginRequest イベントまたは AuthenticateRequest イベントで書き換えを実行すると、 UrlAuthorizationModule に書き換えられた URL が表示されます。 つまり、Web.config ファイル内の location> 要素を使用<して特定の URL の承認を指定する場合は、書き換えられた URL を参照する必要があります。

これらの微妙な点を修正するには、 AuthorizeRequest イベントで URL の書き換えを実行する必要があります。 この方法では URL 承認が修正され、認証の異常が発生しますが、ファイル承認が機能しなくなったという新しいしわが発生します。 Windows 認証を使用する場合、FileAuthorizationModule は、認証されたユーザーが特定の ASP.NET ページにアクセスするための適切なアクセス権を持っていることを確認します。

一連のユーザーが C:\Inetput\wwwroot\info\employee.aspx に Windows レベルのファイル アクセス権を持っていない場合を想像してください。このようなユーザーが /info/employee.aspx?empID=1001 にアクセスしようとすると、承認エラーが発生します。 ただし、URL の書き換えを AuthenticateRequest イベントに移動した場合、 FileAuthorizationModule が セキュリティ設定を確認しても、要求されているファイルは /people/ScottMitchell.aspx と見なされます。URL はまだ書き換えられていないためです。 したがって、ファイル承認チェックが渡され、このユーザーは書き換えられた URL /info/employee.aspx?empID=1001 の内容を表示できます。

では、HTTP モジュールで URL 書き換えをいつ実行する必要がありますか? 使用している認証の種類によって異なります。 認証を使用していない場合は、BeginRequest、AuthenticateRequest、または AuthorizeRequest で URL の書き換えが行われるかどうかは関係ありません。 フォーム認証を使用していて、Windows 認証を使用していない場合は、AuthorizeRequest イベント ハンドラーに URL の書き換えを配置します。 最後に、Windows 認証を使用している場合は、BeginRequest イベントまたは AuthenticateRequest イベント中に URL の書き換えをスケジュールします。

HTTP ハンドラーでの URL 書き換え

URL の書き換えは、HTTP ハンドラーまたは HTTP ハンドラー ファクトリでも実行できます。 HTTP ハンドラーは、特定の種類の要求のコンテンツを生成するクラスであることを思い出してください。HTTP ハンドラー ファクトリは、特定の種類の要求のコンテンツを生成できる HTTP ハンドラーのインスタンスを返すクラスです。

この記事では、ASP.NET Web ページ用の URL 書き換え HTTP ハンドラー ファクトリの作成について説明します。 HTTP ハンドラー ファクトリは、GetHandler() メソッドを含む IHttpHandlerFactory インターフェイスを実装する必要があります。 適切な HTTP モジュールを初期化した後、ASP.NET エンジンは、指定された要求に対して呼び出す HTTP ハンドラーまたは HTTP ハンドラー ファクトリを決定します。 HTTP ハンドラー ファクトリを呼び出す場合、ASP.NET エンジンは、その HTTP ハンドラー ファクトリの GetHandler() メソッドを呼び出して、Web 要求の HttpContext を他の情報と共に渡します。 その後、HTTP ハンドラー ファクトリは、要求を処理できる IHttpHandler を実装するオブジェクトを返す必要があります。

HTTP ハンドラーを介して URL 書き換えを実行するために、 GetHandler() メソッドが要求されたパスをチェックして書き換える必要があるかどうかを判断する HTTP ハンドラー ファクトリを作成できます。 その場合は、前述のように、渡された HttpContext オブジェクトの RewritePath() メソッドを呼び出すことができます。 最後に、HTTP ハンドラー ファクトリは 、System.Web.UI.PageParser クラスの GetCompiledPageInstance() メソッドによって返される HTTP ハンドラーを返すことができます。 (これは、組み込みの ASP.NET Web ページ HTTP ハンドラー ファクトリ である PageHandlerFactory が機能するのと同じ手法です)。

すべての HTTP モジュールは、カスタム HTTP ハンドラー ファクトリがインスタンス化される前に初期化されるため、HTTP ハンドラー ファクトリを使用すると、イベントの後者の段階で URL の書き換えを行う場合と同じ課題が発生します。つまり、ファイルの承認は機能しません。 そのため、Windows 認証とファイルの承認に依存する場合は、URL の書き換えに HTTP モジュール アプローチを使用する必要があります。

次のセクションでは、再利用可能な URL 書き換えエンジンの構築について説明します。 この記事のコード ダウンロードで利用できる URL 書き換えエンジンの調査に続いて、残りの 2 つのセクションで、実際の URL 書き換えの使用方法を調べていきます。 まず、URL 書き換えエンジンを使用する方法を見て、簡単な URL 書き換えの例を見ていきます。 その後、書き換えエンジンの正規表現機能の機能を利用して、真に "ハッキング可能な" URL を提供します。

URL 書き換えエンジンの構築

ASP.NET Web アプリケーションで URL 書き換えを実装する方法を説明するために、URL 書き換えエンジンを作成しました。 この書き換えエンジンは、次の機能を提供します。

  • URL 書き換えエンジンを使用する ASP.NET ページ開発者は、Web.config ファイルで書き換えルールを指定できます。
  • 書き換えルールでは、正規表現を使用して強力な書き換えルールを使用できます。
  • URL 書き換えは、HTTP モジュールまたは HTTP ハンドラーを使用するように簡単に構成できます。

この記事では、HTTP モジュールだけで URL の書き換えを調べます。 HTTP ハンドラーを使用して URL の書き換えを実行する方法については、この記事でダウンロードできるコードを参照してください。

URL 書き換えエンジンの構成情報の指定

Web.config ファイル内の書き換えルールの構造を調べてみましょう。 まず、HTTP モジュールまたは HTTP ハンドラーを使用して URL の書き換えを実行する場合は、Web.config ファイルで を指定する必要があります。 ダウンロードでは、Web.config ファイルにコメントアウトされた 2 つのエントリが含まれています。

<!--
<httpModules>
   <add type="URLRewriter.ModuleRewriter, URLRewriter" 
        name="ModuleRewriter" />
</httpModules>
-->

<!--
<httpHandlers>
   <add verb="*" path="*.aspx" 
        type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
</httpHandlers>
-->

<書き換えに HTTP モジュールを使用するには httpModules> エントリをコメントアウトします。代わりに httpHandlers> エントリをコメントアウト<して、書き換えに HTTP ハンドラーを使用します。

書き換えに HTTP モジュールまたは HTTP ハンドラーのどちらを使用するかを指定するだけでなく、Web.config ファイルには書き換え規則が含まれています。 書き換えルールは、要求された URL で検索するパターンと、パターンを置き換える文字列 (見つかった場合) の 2 つの文字列で構成されます。 この情報は、次の構文を使用して、Web.config ファイルで表されます。

<RewriterConfig>
   <Rules>
   <RewriterRule>
      <LookFor>pattern to look for</LookFor>
      <SendTo>string to replace pattern with</SendTo>
   </RewriterRule>
   <RewriterRule>
      <LookFor>pattern to look for</LookFor>
      <SendTo>string to replace pattern with</SendTo>
   </RewriterRule>
   ...
   </Rules>
</RewriterConfig>

各書き換えルールは、RewriteerRule> 要素によって<表されます。 検索するパターンは LookFor> 要素によって<指定され、見つかったパターンを に置き換える文字列は SentTo> 要素に<入力されます。 これらの書き換えルールは、上から下に評価されます。 一致するものが見つかった場合は、URL が書き換えられ、書き換えルールの検索が終了します。

LookFor> 要素で<パターンを指定する場合は、正規表現を使用して一致と文字列の置換を実行します。 (ここでは、正規表現を使用してパターンを検索する方法を示す実際の例を少し見ていきます)。パターンは正規表現であるため、正規表現で予約文字である文字は必ずエスケープしてください。 (正規表現の予約文字には、.、?、^、$などがあります。これらは、前に円記号 (\ など) を付けることでエスケープできます。リテラルピリオドに一致する場合は )。)

HTTP モジュールを使用した URL 書き換え

HTTP モジュールの作成は、 IHttpModule インターフェイスを実装するクラスを作成するのと同じくらい簡単です。 IHttpModule インターフェイスは、次の 2 つのメソッドを定義します。

  • Init(HttpApplication). このメソッドは、HTTP モジュールが初期化されるときに発生します。 このメソッドでは、イベント ハンドラーを適切な HttpApplication イベントに関連付けます。
  • Dispose()。 このメソッドは、要求が完了し、IIS に送り返されたときに呼び出されます。 ここで最終的なクリーンアップを実行する必要があります。

URL 書き換え用の HTTP モジュールの作成を容易にするために、抽象基本クラス BaseModuleRewriter を作成することから始めました。 このクラスは IHttpModule を実装します。 Init() イベントでは、HttpApplicationAuthorizeRequest イベントを BaseModuleRewriter_AuthorizeRequest メソッドに結び付けます。 BaseModuleRewriter_AuthorizeRequest メソッドは、Init() メソッドに渡された HttpApplication オブジェクトと共に、要求された Path を渡すクラスの Rewrite() メソッドを呼び出します。 Rewrite() メソッドは抽象です。つまり、BaseModuleRewriter クラスでは、Rewrite() メソッドにはメソッド本体がありません。むしろ、BaseModuleRewriter から派生するクラスは、このメソッドをオーバーライドし、メソッド本体を提供する必要があります

この基本クラスを配置すると、ここで行う必要があるのは、Rewrite() をオーバーライドし、そこで URL 書き換えロジックを実行する BaseModuleRewriter から派生したクラスを作成することにすぎません。 BaseModuleRewriter のコードを次に示します。

public abstract class BaseModuleRewriter : IHttpModule
{
   public virtual void Init(HttpApplication app)
   {
      // WARNING!  This does not work with Windows authentication!
      // If you are using Windows authentication, 
      // change to app.BeginRequest
      app.AuthorizeRequest += new 
         EventHandler(this.BaseModuleRewriter_AuthorizeRequest);
   }

   public virtual void Dispose() {}

   protected virtual void BaseModuleRewriter_AuthorizeRequest(
     object sender, EventArgs e)
   {
      HttpApplication app = (HttpApplication) sender;
      Rewrite(app.Request.Path, app);
   }

   protected abstract void Rewrite(string requestedPath, 
     HttpApplication app);
}

BaseModuleRewriter クラスが AuthorizeRequest イベントで URL の書き換えを実行することに注意してください。 ファイルの承認でWindows 認証を使用する場合は、BeginRequest イベントまたは AuthenticateRequest イベントで URL の書き換えが実行されるように、これを変更する必要があることを思い出してください。

ModuleRewriter クラスは BaseModuleRewriter クラスを拡張し、実際の URL 書き換えを実行します。 ModuleRewriter には、次に示す 1 つのオーバーライドされたメソッド Rewrite()が含まれています。

protected override void Rewrite(string requestedPath, 
   System.Web.HttpApplication app)
{
   // get the configuration rules
   RewriterRuleCollection rules = 
     RewriterConfiguration.GetConfig().Rules;

   // iterate through each rule...
   for(int i = 0; i < rules.Count; i++)
   {
      // get the pattern to look for, and 
      // Resolve the Url (convert ~ into the appropriate directory)
      string lookFor = "^" + 
        RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, 
        rules[i].LookFor) + "$";

      // Create a regex (note that IgnoreCase is set...)
      Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);

      // See if a match is found
      if (re.IsMatch(requestedPath))
      {
         // match found - do any replacement needed
         string sendToUrl = 
RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, 
            re.Replace(requestedPath, rules[i].SendTo));

         // Rewrite the URL
         RewriterUtils.RewriteUrl(app.Context, sendToUrl);
         break;      // exit the for loop
      }
   }
}

Rewrite() メソッドは、最初に、Web.config ファイルから一連の書き換えルールを取得します。 その後、書き換えルールを一度に 1 つずつ反復処理し、ルールごとに LookFor プロパティを取得し、正規表現を使用して、要求された URL で一致が見つかったかどうかを判断します。

一致するものが見つかった場合、要求されたパスに対して、 SendTo プロパティの値を使用して正規表現の置換が実行されます。 この置換された URL は、 RewriteerUtils.RewriteUrl() メソッドに渡されます。 RewriteerUtils は、URL 書き換え HTTP モジュールと HTTP ハンドラーの両方で使用されるいくつかの静的メソッドを提供するヘルパー クラスです。 RewriteerUrl() メソッドは、HttpContext オブジェクトの RewriteUrl() メソッドを呼び出すだけです。

メモ 正規表現の一致と置換を実行すると、 RewriterUtils.ResolveUrl() の呼び出しが行われることがわかります。 このヘルパー メソッドは、文字列内の ~ のインスタンスをアプリケーションのパスの値に置き換えるだけです。

この記事では、URL 書き換えエンジンのコード全体をダウンロードできます。 最もドイツ語的な部分を調べましたが、Web.config ファイル内の XML 形式の書き換えルールをオブジェクトに逆シリアル化するためのクラスや、URL 書き換え用の HTTP ハンドラー ファクトリなどの他のコンポーネントもあります。 この記事の残りの 3 つのセクションでは、URL 書き換えの実際の使用方法について説明します。

URL 書き換えエンジンを使用した単純な URL 書き換えの実行

URL 書き換えエンジンの動作を示すために、単純な URL 書き換えを利用する ASP.NET Web アプリケーションを構築してみましょう。 オンラインで各種製品を販売している会社で働いているとします。 これらの製品は、次のカテゴリに分類されます。

カテゴリ ID カテゴリ名
1 飲み物
2 調味料
3 菓子
4 乳製品
... ...

既に ListProductsByCategory.aspx という名前の ASP.NET Web ページを作成し、クエリ文字列の Category ID 値を受け取り、そのカテゴリに属するすべての製品を表示しているとします。 では、販売のために飲料を表示したいユーザーは、ListProductsByCategory.aspx にアクセスしますか?CategoryID=1。酪農製品を表示したいユーザーは ListProductsByCategory.aspx にアクセスしますか?CategoryID=4。 また、販売する製品のカテゴリを一覧表示する ListCategories.aspx というページがあるとします。

ユーザーに表示される URL はユーザーにとって意味を持たないし、"ハッキング可能性" も提供しないため、URL の書き換えの場合は明らかです。むしろ、ユーザーが /Products/Beverages.aspx にアクセスしたときに、その URL が ListProductsByCategory.aspx に書き換えられるように、URL の書き換えを使用してみましょう。CategoryID=1。 これを実現するには、Web.config ファイル内の次の URL 書き換え規則を使用します。

<RewriterConfig>
   <Rules>
      <!-- Rules for Product Lister -->
      <RewriterRule>
         <LookFor>~/Products/Beverages\.aspx</LookFor>
         <SendTo>~/ListProductsByCategory.aspx?CategoryID=1</SendTo>
      </RewriterRule>
      <RewriterRule>
   </Rules>
</RewriterConfig>

ご覧のように、このルールでは、ユーザーが要求したパスが /Products/Beverages.aspx であるかどうかを検索します。 その場合は、URL を /ListProductsByCategory.aspx として書き換えますか?CategoryID=1。

メモLookFor> 要素は<、Beverages.aspx のピリオドをエスケープします。 これは、 <LookFor> 値が正規表現パターンで使用され、ピリオドは正規表現の特殊文字であり、"任意の文字に一致する" ことを意味します。つまり、/Products/BeveragesQaspx の URL は一致します。 (\.) を使用してピリオドをエスケープすることで、古い文字ではなくリテラルピリオドと一致することを示しています。

このルールを設定すると、ユーザーが /Products/Beverages.aspx にアクセスすると、販売中の飲料が表示されます。 図 3 は、/Products/Beverages.aspx にアクセスしているブラウザーのスクリーンショットを示しています。 ブラウザーのアドレス バーの URL には /Products/Beverages.aspx と読み取りますが、ユーザーには実際には ListProductsByCategory.aspx の内容が表示されていることに注意してください。CategoryID=1。 (実際、Web サーバーには /Products/Beverages.aspx ファイルもまったく存在しません)。

ms972974.urlrewriting_fig03(en-us,MSDN.10).gif

図 3: URL の書き換え後のカテゴリの要求

/Products/Beverages.aspx と同様に、次に他の製品カテゴリの書き換えルールを追加します。 これには、Web.config ファイルの Rules> 要素内に、追加の< RewriterRule >要素を追加するだけです。< デモの書き換えルールの完全なセットについては、ダウンロードのWeb.config ファイルを参照してください。

URL をより "ハッキング可能" にするには、ユーザーが単に /Products/Beverages.aspx から Beverages.aspx をハッキングし、製品カテゴリの一覧を表示できる場合に便利です。 一見すると、これは簡単なタスクのように見えることがあります。単に、/Products/ を /ListCategories.aspx にマップする書き換えルールを追加するだけです。 ただし、細かい微妙さがあります。最初に /Products/ ディレクトリを作成し、/Products/ ディレクトリに空の Default.aspx ファイルを追加する必要があります。

これらの追加の手順を実行する必要がある理由を理解するには、URL 書き換えエンジンが ASP.NET レベルにあることを思い出してください。 つまり、ASP.NET エンジンに要求を処理する機会が与えられなければ、URL 書き換えエンジンが受信 URL を検査する方法はありません。 さらに、IIS は、要求されたファイルに適切な拡張子がある場合にのみ、ASP.NET エンジンに受信要求を送信します。 そのため、ユーザーが /Products/にアクセスすると、IIS にはファイル拡張子が表示されないため、ディレクトリをチェックして、既定のファイル名の 1 つを持つファイルが存在するかどうかを確認します。 (Default.aspx、Default.htm、Default.asp など。これらの既定のファイル名は、[IIS 管理] ダイアログ ボックスの [Web サーバーのプロパティ] ダイアログ ボックスの [ドキュメント] タブで定義されます)。もちろん、/Products/ ディレクトリが存在しない場合、IIS は HTTP 404 エラーを返します。

そのため、/Products/ ディレクトリを作成する必要があります。 さらに、このディレクトリ Default.aspx に 1 つのファイルを作成する必要があります。 これにより、ユーザーが /Products/にアクセスすると、IIS によってディレクトリが検査され、Default.aspx という名前のファイルが存在することを確認し、ASP.NET エンジンに処理を渡します。 その後、URL リライターは URL の書き換えに関する問題を受け取ります。

ディレクトリと Default.aspx ファイルを作成したら、次の書き換えルールを Rules> 要素に<追加します。

<RewriterRule>
   <LookFor>~/Products/Default\.aspx</LookFor>
   <SendTo>~/ListCategories.aspx</SendTo>
</RewriterRule>

このルールを設定すると、ユーザーが /Products/ または /Products/Default.aspx にアクセスすると、図 4 に示す製品カテゴリの一覧が表示されます。

ms972974.urlrewriting_fig04(en-us,MSDN.10).gif

図 4: URL に "hackability" を追加する

ポストバックの処理

書き換える URL にサーバー側の Web フォームが含まれており、ポストバックを実行する場合、フォームがポストバックすると、基になる URL が使用されます。 つまり、ユーザーがブラウザー /Products/Beverages.aspx に入ると、ブラウザーのアドレス バー /Products/Beverages.aspx に引き続き表示されますが、ListProductsByCategory.aspx のコンテンツが表示されます。CategoryID=1。 ListProductsByCategory.aspx がポストバックを実行すると、ユーザーは ListProductsByCategory.aspx にポストバックされますか?CategoryID=1。/Products/Beverages.aspx ではありません。 これは何も壊れませんが、ボタンをクリックしたときに URL が突然変わるのをユーザーの観点から見ると混乱する可能性があります。

この動作が発生する理由は、Web フォームがレンダリングされるときに、その action 属性を Request オブジェクトのファイル パスの値に明示的に設定するためです。 もちろん、Web フォームがレンダリングされるまでに、URL は /Products/Beverages.aspx から ListProductsByCategory.aspx に書き換えられますか?CategoryID=1。 つまり、Request オブジェクトは、ユーザーが ListProductsByCategory.aspx にアクセスしていることを報告していますか?CategoryID=1。 この問題は、単にアクション属性をレンダリングしないサーバー側のフォームを使用することで修正できます。 (フォームに action 属性が含まれていない場合、ブラウザーは既定でポストバックします)。

残念ながら、Web フォームではアクション属性を明示的に指定することはできません。また、アクション属性のレンダリングを無効にするプロパティを設定することもできません。 代わりに、 System.Web.HtmlControls.HtmlForm クラスを自分で拡張し、 RenderAttribute() メソッドをオーバーライドし、アクション属性をレンダリングしないことを明示的に示す必要があります。

継承の機能により、 HtmlForm クラスのすべての機能を取得でき、必要な動作を実現するためにスキャンされた数行のコードを追加するだけで済みます。 カスタム クラスの完全なコードを次に示します。

namespace ActionlessForm {
  public class Form : System.Web.UI.HtmlControls.HtmlForm
  {
     protected override void RenderAttributes(HtmlTextWriter writer)
     {
        writer.WriteAttribute("name", this.Name);
        base.Attributes.Remove("name");

        writer.WriteAttribute("method", this.Method);
        base.Attributes.Remove("method");

        this.Attributes.Render(writer);

        base.Attributes.Remove("action");

        if (base.ID != null)
           writer.WriteAttribute("id", base.ClientID);
     }
  }
}

オーバーライドされた RenderAttributes() メソッドのコードには、 HtmlForm クラスの RenderAttributes() メソッドの正確なコードが含まれていますが、action 属性は設定されません。 (私はLutz Roederの リフレクター を使用して HtmlForm クラスのソースコードを表示しました。

このクラスを作成してコンパイルしたら、ASP.NET Web アプリケーションで使用するには、まず Web アプリケーションの References フォルダーに追加します。 次に、 HtmlForm クラスの代わりに使用するには、ASP.NET Web ページの上部に次のコードを追加します。

<%@ Register TagPrefix="skm" Namespace="ActionlessForm" 
   Assembly="ActionlessForm" %>

次に、 がある <form runat="server">場所で、 を次のように置き換えます。

<skm:Form id="Form1" method="post" runat="server">

終了タグを次のように </form> 置き換えます。

</skm:Form>

ListProductsByCategory.aspx では、このカスタム Web フォーム クラスの動作を確認できます。このクラスは、この記事のダウンロードに含まれています。 また、ダウンロードには、アクションレス Web フォーム用の Visual Studio .NET プロジェクトも含まれています。

メモ 書き換える URL がポストバックを実行しない場合は、このカスタム Web フォーム クラスを使用する必要はありません。

真に "ハッキング可能" な URL の作成

前のセクションで示した単純な URL 書き換えは、URL 書き換えエンジンを新しい書き換え規則で構成する方法を示しました。 ただし、このセクションで説明するように、正規表現を使用すると、書き換えルールの真の力が発揮されます。

ブログは最近ますます人気が高まり、 誰もが 独自のブログを持っているようです。 ブログに慣れていない場合は、通常はオンライン ジャーナルとして機能する個人用ページが更新されることがよくあります。 ほとんどのブロガーは、日々の出来事について書くだけで、映画のレビュー、スポーツチーム、コンピュータ技術など、特定のテーマに関するブログに焦点を当てています。

作成者に応じて、ブログは 1 日に数回から毎週 1 回または 2 回更新されます。 通常、ブログホームページには最新の10のエントリが表示されますが、事実上すべてのブログソフトウェアは、訪問者が古い投稿を読むことができるアーカイブを提供します。 ブログは、"hackable" URL の優れたアプリケーションです。 URL /2004/02/14.aspx で見つけたブログのアーカイブを検索しているときに想像してみてください。 2004 年 2 月 14 日に作成された投稿を読んでも驚いたでしょうか。 さらに、2004 年 2 月のすべての投稿を表示することもできます。その場合は、URL を /2004/02/にハッキングしてみてください。 2004 件の投稿をすべて表示するには、/2004/にアクセスしてみてください。

ブログを維持する場合は、このレベルの URL "hackability" を訪問者に提供すると便利です。 多くのブログ エンジンがこの機能を提供していますが、URL の書き換えを使用して実現する方法を見てみましょう。

まず、日、月、または年ごとにブログ エントリを表示する 1 つの ASP.NET Web ページが必要です。 このようなページ ShowBlogContent.aspx があり、クエリ文字列パラメーター year、month、day を受け取るとします。 2004 年 2 月 14 日の投稿を表示するには、ShowBlogContent.aspx?year=2004&month=2&day=14 にアクセスします。 2004 年 2 月のすべての投稿を表示するには、ShowBlogContent.aspx?year=2004&month=2 にアクセスします。 最後に、2004 年のすべての投稿を表示するには、ShowBlogContent.aspx?year=2004 に移動します。 (ShowBlogContent.aspx のコードは、この記事のダウンロードにあります)。

そのため、ユーザーが /2004/02/14.aspx にアクセスした場合は、URL を ShowBlogContent.aspx?year=2004&month=2&day=14 に書き換える必要があります。 3 つのケースすべて — URL で年、月、日が指定されている場合。URL が年と月のみを指定する場合。URL で yes のみが指定されている場合は、次の 3 つの書き換え規則で処理できます。

<RewriterConfig>
   <Rules>
      <!-- Rules for Blog Content Displayer -->
      <RewriterRule>
         <LookFor>~/(\d{4})/(\d{2})/(\d{2})\.aspx</LookFor>
         <SendTo>~/ShowBlogContent.aspx?year=$1&amp;month=$2&amp;day=$3</SendTo>
      </RewriterRule>
      <RewriterRule>
         <LookFor>~/(\d{4})/(\d{2})/Default\.aspx</LookFor>
         <SendTo><![CDATA[~/ShowBlogContent.aspx?year=$1&month=$2]]></SendTo>
      </RewriterRule>
      <RewriterRule>
         <LookFor>~/(\d{4})/Default\.aspx</LookFor>
         <SendTo>~/ShowBlogContent.aspx?year=$1</SendTo>
      </RewriterRule>
   </Rules>
</RewriterConfig>

これらの書き換えルールは、正規表現の力を示しています。 最初のルールでは、パターン (\d)/(\d{4})/(\d{2}{2})\.aspx の URL を検索します。 プレーンな英語では、4 桁の文字列の後にスラッシュ、2 桁の数字、スラッシュ、2 桁の後に .aspx が続く文字列と一致します。 各桁のグループ化を囲むかっこは重要です。これにより、対応する <SendTo> プロパティのかっこ内で一致する文字を参照できます。 具体的には、1 番目、2 番目、3 番目のかっこグループに対してそれぞれ $1、$2、および $3 を使用して、一致するかっこグループを参照できます。

メモWeb.config ファイルは XML 形式であるため、要素のテキスト部分の 、<、 > などの&文字をエスケープする必要があります。 最初のルールの <SendTo> 要素では、 & は amp; に &エスケープされます。 2 番目のルールの <SendTo> では、![ を使用して別の手法が<使用されます。CDATA[...]]>要素内の内容をエスケープする必要はありません。 どちらの方法も受け入れ可能であり、同じ終わりを実現します。

図 5、6、および 7 は、動作中の URL の書き換えを示しています。 データは実際に私のブログから引き出されています。 http://ScottOnWriting.NET 図 5 では、2003 年 11 月 7 日の投稿が示されています。図 6 では、2003 年 11 月のすべての投稿が示されています。図 7 は、2003 年のすべての投稿を示しています。

ms972974.urlrewriting_fig05(en-us,MSDN.10).gif

図 5: 2003 年 11 月 7 日の投稿

ms972974.urlrewriting_fig06(en-us,MSDN.10).gif

図 6: 2003 年 11 月のすべての投稿

ms972974.urlrewriting_fig07(en-us,MSDN.10).gif

図 7: 2003 年のすべての投稿

メモURL 書き換えエンジンでは、LookFor> 要素に正規表現パターンが<必要です。 正規表現に慣れていない場合は、以前の記事「 正規表現の概要」を読むことを検討してください。 また、一般的に使用される正規表現や、独自に作成された正規表現を共有するためのリポジトリを手に入れるのに最適な場所が RegExLib.com

必要なディレクトリ構造の構築

/2004/03/19.aspx に対して要求が送信されると、IIS は .aspx 拡張機能をメモし、ASP.NET エンジンに要求をルーティングします。 要求が ASP.NET エンジンのパイプラインを通過すると、URL は ShowBlogContent.aspx?year=2004 month=03 day=19 に書き換えられ、訪問者には 2004&年 3&月 19 日のブログ エントリが表示されます。 しかし、ユーザーが /2004/03/に移動するとどうなりますか? ディレクトリ /2004/03/がない限り、IIS は 404 エラーを返します。 さらに、要求が ASP.NET エンジンに渡されるように、このディレクトリに Default.aspx ページが必要です。

そのため、この方法では、ディレクトリに Default.aspx ページを使用して、ブログ エントリがある年ごとにディレクトリを手動で作成する必要があります。 さらに、毎年のディレクトリでは、12 個のディレクトリ (01、02、...、12) を手動で作成し、それぞれ Default.aspx ファイルを使用する必要があります。 (前のデモでは、/Products/ にアクセスすると ListCategories.aspx が正しく表示されるように、前のデモで同じことを行う必要がありました (Default.aspx ファイルを使用して /Products/ ディレクトリを追加する) ことを思い出してください。

明らかに、このようなディレクトリ構造を追加すると、問題になる可能性があります。 この問題の回避策は、すべての受信 IIS 要求を ASP.NET エンジンにマップすることです。 これにより、URL /2004/03/ にアクセスした場合でも、IIS は /2004/03/ ディレクトリが存在しない場合でも、ASP.NET エンジンに要求を忠実に渡します。 ただし、この方法を使用すると、ASP.NET エンジンは、画像、CSS ファイル、外部 JavaScript ファイル、Macromedia Flash ファイルなど、Web サーバーへのすべての種類の受信要求を処理します。

すべてのファイルの種類を処理する方法については、この記事の範囲をはるかに超えています。 ただし、この手法を使用する ASP.NET Web アプリケーションの例については、 を参照してください 。テキスト。オープンソースのブログ エンジンです。 .テキストは、すべての要求を ASP.NET エンジンにマップするように構成できます。 一般的な静的ファイルの種類 (画像、CSS ファイルなど) を提供する方法を認識するカスタム HTTP ハンドラーを使用して、すべてのファイルの種類の処理を処理できます。

まとめ

この記事では、 HttpContext クラスの RewriteUrl() メソッドを使用して、ASP.NET レベルで URL の書き換えを実行する方法について説明しました。 見たとおり、 RewriteUrl() は 特定 の HttpContext のRequest プロパティを更新し、要求されているファイルとパスを更新します。 実際には、ユーザーの観点からは、特定の URL にアクセスしていますが、実際には Web サーバー側で別の URL が要求されているということです。

URL は、HTTP モジュールまたは HTTP ハンドラーのいずれかで書き換えることができます。 この記事では、HTTP モジュールを使用して書き換えを実行し、パイプラインのさまざまな段階で書き換えを実行した結果を調べました。

もちろん、ASP.NET レベルの書き換えでは、要求が IIS から ASP.NET エンジンに正常に渡された場合にのみ、URL の書き換えが行われます。 これは、ユーザーが .aspx 拡張子を持つページを要求したときに自然に発生します。 ただし、実際には存在しない可能性のある URL をユーザーが入力できるようにしたいが、既存の ASP.NET ページに書き換える場合は、モック ディレクトリと Default.aspx ページを作成するか、またはすべての受信要求が ASP.NET エンジンに盲目的にルーティングされるように IIS を構成する必要があります。

ASP.NET: ヒント、チュートリアル、コード

Microsoft ASP.NET チームとの Microsoft ASP.NET コーディング戦略

C の例を使用した基本的な ASP.NET#

参照された作業

URL の書き換えは、ASP.NET と競合するサーバー側 Web テクノロジの両方で大きな注目を集めているトピックです。 たとえば、Apache Web サーバーには、mod_rewriteと呼ばれる URL 書き換え用のモジュール 用意されています。 mod_rewriteは堅牢な書き換えエンジンであり、HTTP ヘッダーやサーバー変数などの条件に基づく書き換え規則と、正規表現を使用する規則の書き換えを提供します。 mod_rewriteの詳細については、「Apache Web サーバーを使用した URL 書き換えのユーザー ガイド」をチェック。

ASP.NET を使用した URL の書き換えに関する記事が多数あります。 Rewrite.NET - .NET 用 URL 書き換えエンジン では、mod_rewriteの正規表現規則を模倣する URL 書き換えエンジンの作成を調べます。 ASP.NET を使用した URL 書き換え では、ASP の概要も説明します。NET の URL 書き換え機能。 Ian Griffiths には、この記事で説明するポストバックの問題など、ASP.NET を使用した URL の書き換えに関連するいくつかの注意事項に関する ブログ エントリ があります。 Fabrice Marguerie (詳細) と Jason Salas (詳細) の両方に、URL の書き換えを使用して検索エンジンの配置を向上させるブログ全体があります。

 

筆者について

5 冊の書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、過去 5 年間 Microsoft Web テクノロジと協力してきました。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼は、またはで見つけることができますhttp://ScottOnWriting.NET彼のブログを介して到達mitchell@4guysfromrolla.comすることができます.

© Microsoft Corporation. All rights reserved.