URL Rewrite Module 用のルール テンプレートの開発
このチュートリアルでは、URL Rewrite Module のルール テンプレートを開発する方法について説明します。 Web サイトに対して特定のドメインの使用を強制する、書き換えルールの生成に使用できるルール テンプレートを作成します。
テンプレートの概要
[Canonical Domain Name] (正規ドメイン名) ルール テンプレートを使用すると、Web サイトに正規ドメイン名を強制するために使用される書き換えルールの作成を簡略化できます。 ユーザーは、このテンプレートを [Add rule(s)] (ルールの追加) ダイアログから選択できます。
続いて、ユーザーは使用するドメイン名を指定できます。
その後に、そのテンプレートで以下のように書き換えルールを生成します。
前提条件
このチュートリアルを進める前に、記事「単純な IIS マネージャー モジュールを作成する方法」のタスクを完了して、IIS マネージャーの拡張性の基本的な概念を理解しておくことをお勧めします。
ルール テンプレートの VS2008 プロジェクト
このルール テンプレートの Visual Studio 2008 プロジェクト全体をこちらからダウンロードできます。
ルール テンプレートを実装する
リモート管理をサポートするために、すべての IIS マネージャー UI コンポーネントが特定の設計パターンに従って実装されます。 モジュールの実装は、次の部分から構成されます。
- クライアント側のユーザー インターフェイスとサービス プロキシ
- IIS 構成を管理するためのサーバー側サービス
すべてのユーザー インターフェイス固有の実装はクライアント側に置かれ、場合によってはそれがリモート クライアント コンピューターになります。 IIS 構成に実際に変更を加えるすべての機能はサーバー側にサービスとして実装されるため、すべてのサーバー構成 API にアクセスできます。 クライアント側のコントロールでは、サービス プロキシを介してサービスと対話します。
ユーザーが IIS リモート マネージャーを使用してルールを作成するときにテンプレートが機能するよう、同じパターンに従ってルール テンプレートを実装することをお勧めします。 次のセクションでは、ルール テンプレート サービスおよびクライアントを実装する方法について説明します。
クライアント側ユーザー インターフェイスを実装する
モジュールを作成する
まず、モジュールを作成する必要があります。これは、すべての拡張性オブジェクトのクライアント内でのメイン エントリ ポイントです。 その手順を次に示します。
- 記事「単純な IIS マネージャー モジュールを作成する方法」のタスク 1 と 2 で説明されている手順に従って、Visual Studio プロジェクトを作成して構成します。 プロジェクトに "CanonicalDomainTemplateClient" という名前を付けます。
- [プロジェクト] メニューから [Add References] (参照の追加) を選択し、\Windows\System32\inetsrv にある Microsoft.Web.Management.dll への参照を追加します。
- もう一度 [Add References] (参照の追加) を選択し、\Program Files\Reference Assemblies\Microsoft\IIS にある Microsoft.Web.Management.Rewrite.Client.dll への参照を追加します。
- [Add Reference] (参照の追加) をもう一度選択し、System.Windows.Forms.dll への参照を追加します
- [プロジェクト] メニューからオプション [新しい項目の追加] を選択します。 [新しい項目の追加] ダイアログ ボックスで、クラス テンプレートを選択し、ファイルの名前として「CanonicalDomainModule.cs」と入力します。
- 以下のようにコードを変更します。
using System;
using Microsoft.Web.Management.Server;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Iis.Rewrite;
namespace CanonicalDomainTemplate
{
internal class CanonicalDomainModule: Module
{
protected override void Initialize(IServiceProvider serviceProvider, ModuleInfo moduleInfo)
{
base.Initialize(serviceProvider, moduleInfo);
IExtensibilityManager extensibilityManager = (IExtensibilityManager)GetService(typeof(IExtensibilityManager));
extensibilityManager.RegisterExtension(typeof(RewriteTemplateFeature), new CanonicalDomainFeature(this));
}
}
}
このコードでは、クラス CanonicalDomainFeature (ルール テンプレート機能を実装します) の新しいインスタンスを初期化します。 このクラスのインスタンスは、RewriteTemplateFeature 型の拡張機能の登録に使用されます。この型が、すべてのルール テンプレートの派生元です。
書き換えテンプレート機能を作成する
ルール テンプレートを実装するクラスを定義する場合、このクラスを RewriteTemplateFeature クラスから派生させる必要があります。 これは、すべての URL 書き換えルール テンプレートで使用される親クラスです。
- [プロジェクト] メニューの [新しい項目の追加] オプションを選択します。 クラス テンプレートを選択し、ファイル名として「CanonicalDomainFeature.cs」と入力します。
- 以下のようにコードを変更します。
using System;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Iis.Rewrite;
using System.Windows.Forms;
using System.Collections;
namespace CanonicalDomainTemplate
{
class CanonicalDomainFeature: RewriteTemplateFeature
{
private const string FeatureTitle = "Canonical Domain Name";
private const string FeatureDescription = "Creates a rewrite rule for enforcing canonical domain name for your web site";
public CanonicalDomainFeature(Module module)
: base(module, FeatureTitle, FeatureDescription, Resource.domain_icon16, Resource.domain_icon32)
{
}
public override void Run()
{
CanonicalDomainModuleServiceProxy serviceProxy =
(CanonicalDomainModuleServiceProxy)Connection.CreateProxy(this.Module,
typeof(CanonicalDomainModuleServiceProxy));
CanonicalDomainForm form = new CanonicalDomainForm(serviceProxy);
form.StartPosition = FormStartPosition.CenterParent;
if (form.ShowDialog() == DialogResult.OK)
{
Navigate(GetPageType("Rewrite"));
}
}
/// <summary>
/// Returns the main page for the specified module
/// </summary>
private Type GetPageType(string moduleName)
{
IControlPanel controlPanel = (IControlPanel)GetService(typeof(IControlPanel));
Module module = (Module)Connection.Modules[moduleName];
if (module != null)
{
ICollection pageInfos = controlPanel.GetPages(module);
foreach (ModulePageInfo pageInfo in pageInfos)
{
if (pageInfo.IsEnabled && !pageInfo.PageType.IsAssignableFrom(typeof(IModuleChildPage)))
{
return pageInfo.PageType;
}
}
}
return null;
}
}
}
このコードでは、次のことが行われます。
- ルール テンプレートの名前とタイトルを定義します
- 名前、タイトル、アイコンを基底クラスのコンストラクターに渡し、[Add rule(s)] (ルールの追加) ダイアログにすべての登録済みルール テンプレートが表示されるときにそれらが使用されるようにします
- テンプレート ユーザー インターフェイス (WinForm ベースのモーダル ダイアログの CanonicalDomainForm) のレンダリングに使用する Run() メソッドを定義します。 このダイアログで [OK] ボタンをクリックすると、Navigate() メソッドを呼び出して URL Rewrite Module のメイン UI ページが更新されます。
- 最後に、指定されたモジュールのメイン ページの取得に使用されるヘルパー関数 GetPageType を定義します。
サービス プロキシを定義する
リモート クライアントからサービスを呼び出すには、サービス プロキシを指定する必要があります。 これを行うには、CanonicalDomainModuleServiceProxy.cs という名前の別のファイルをプロジェクトに追加し、その中のコードを以下のように変更します。
using System;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Server;
namespace CanonicalDomainTemplate
{
class CanonicalDomainModuleServiceProxy : ModuleServiceProxy
{
public void GenerateRule(string domainName)
{
Invoke("GenerateRule", domainName);
}
}
}
GenerateRule メソッドの実際のサービス実装は、後で追加されます。
ルール テンプレート ダイアログを実装する
ここで、IIS マネージャーのすべてのクライアント側組み込みコードが完了したので、残りの部分として、ルール テンプレートの実際のユーザー インターフェイスを設計して実装します。 これを行うには、次の手順に従います。
[プロジェクト] メニューの [新しい項目の追加] オプションを選択します。 [新しい項目の追加] ダイアログで、[Windows Form] (Windows フォーム) を選択し、「CanonicalDomainForm.cs」という名前を入力します。
Visual Studio の Windows フォーム デザイナーを使用して、フォームにコントロールを配置します。
コード ビューに切り替え、サービス プロキシへの参照を含むことになる、そのクラスのプライベート メンバーを追加します。
private CanonicalDomainModuleServiceProxy _serviceProxy;
同じクラスで、以下のようにコンストラクター コードを変更します。
public CanonicalDomainForm(CanonicalDomainModuleServiceProxy serviceProxy) { _serviceProxy = serviceProxy; InitializeComponent(); }
同じクラスで、サービス プロキシを呼び出してユーザー指定のパラメーターで書き換えルールを生成する、ヘルパー関数を追加します。
private void GenerateRule(string domainName) { try { _serviceProxy.GenerateRule(domainName); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
[OK] ボタンがクリックされたときのためのイベント ハンドラーを追加します。 イベント ハンドラー コードでヘルパー関数 GenerateRule を呼び出し、TextBox コントロールの内容をパラメーターとして渡します。
private void OnOkButtonClick(object sender, EventArgs e) { GenerateRule(_DomainTextBox.Text); }
ルール テンプレートのサービスを実装する
サービスを実装するには、モジュール プロバイダーを作成する必要があります。これは、IIS マネージャーでモジュールを登録するためのエントリ ポイントです。 その手順を次に示します。
記事「単純な IIS マネージャー モジュールを作成する方法」のタスク 1 と 2 で説明されている手順に従って、もう 1 つの Visual Studio プロジェクトを作成して構成します。 プロジェクトに "CanonicalDomainTemplate" という名前を付けます。
[プロジェクト] メニューから [Add References] (参照の追加) を選択し、\Windows\System32\inetsrv にある次のアセンブリへの参照を追加します。
- Microsoft.Web.Administration.dll
- Microsoft.Web.Management.dll
[プロジェクト] メニューからオプション [新しい項目の追加] を選択します。 [新しい項目の追加] ダイアログ ボックスで、クラス テンプレートを選択し、ファイルの名前として「CanonicalDomainModuleProvider.cs」と入力します。
以下のようにコードを変更します (PublicKeyToken は必ず CanonicalDomainTemplate.Client.dll アセンブリの公開キー トークンに置き換えます)
namespace CanonicalDomainTemplate
{
internal sealed class CanonicalDomainModuleProvider : ModuleProvider
{
public override string FriendlyName
{
get
{
return Resource.ModuleFriendlyName;
}
}
public override Type ServiceType
{
get {
return typeof(CanonicalDomainModuleService);
}
}
public override ModuleDefinition GetModuleDefinition(IManagementContext context)
{
if (context != null && string.Compare(context.ClientUserInterfaceTechnology,
"System.Windows.Forms.Control", StringComparison.OrdinalIgnoreCase) != 0)
{
return null;
}
return new ModuleDefinition(Name, "CanonicalDomainTemplate.CanonicalDomainModule,
CanonicalDomainTemplate.Client,Version=1.0.0.0,Culture=neutral,
PublicKeyToken={your key}");
}
public override bool SupportsScope(ManagementScope scope)
{
return true;
}
}
}
このコードでは、すべての種類の接続 (サーバー、サイト、アプリケーション) をサポートする ModuleProvider を作成し、CanonicalDomainModule というクライアント側モジュールを登録します。 また、サーバー側で書き換えルールの生成に使用されるモジュール サービス CanonicalDomainModuleService の種類も登録します。
ルール テンプレートのサービスを作成するには、次の手順に従います。
- [プロジェクト] メニューの [新しい項目の追加] オプションを選択します。 クラス テンプレートを選択し、ファイル名として「CanonicalDomainModuleService.cs」と入力します。
- 以下のようにコードを変更します。
using System;
using System.Collections.Generic;
using Microsoft.Web.Management.Server;
using Microsoft.Web.Administration;
namespace CanonicalDomainTemplate
{
class CanonicalDomainModuleService : ModuleService
{
[ModuleServiceMethod]
public void GenerateRule(string domainName)
{
string sectionPath = "system.webServer/rewrite/rules";
if (ManagementUnit.ConfigurationPath.PathType == ConfigurationPathType.Server)
{
sectionPath = "system.webServer/rewrite/globalRules";
}
ConfigurationSection rulesSection = ManagementUnit.Configuration.GetSection(sectionPath);
ConfigurationElementCollection rulesCollection = rulesSection.GetCollection();
ConfigurationElement ruleElement = rulesCollection.CreateElement("rule");
ruleElement["name"] = @"Canonical domain for " + domainName;
ruleElement["patternSyntax"] = @"Wildcard";
ruleElement["stopProcessing"] = true;
ConfigurationElement matchElement = ruleElement.GetChildElement("match");
matchElement["url"] = @"*";
ConfigurationElement conditionsElement = ruleElement.GetChildElement("conditions");
ConfigurationElementCollection conditionsCollection = conditionsElement.GetCollection();
ConfigurationElement addElement = conditionsCollection.CreateElement("add");
addElement["input"] = @"{HTTP_HOST}";
addElement["negate"] = true;
addElement["pattern"] = domainName;
conditionsCollection.Add(addElement);
ConfigurationElement actionElement = ruleElement.GetChildElement("action");
actionElement["type"] = @"Redirect";
actionElement["url"] = @"http://" + domainName + @"/{R:1}";
actionElement["appendQueryString"] = true;
rulesCollection.Add(ruleElement);
ManagementUnit.Update();
}
}
}
このコードでは、正規ドメインにリダイレクトするためのルールを作成します。
ヒント
書き換えルールを生成するためのコードをすばやく取得するには、IIS 7.0 以降用の構成エディターを使用します。これは Administration Pack for IIS に含まれています。 書き換えルールを作成するためのコードの生成方法の詳細については、こちらの記事を参照してください。
ルール テンプレートを IIS マネージャーに登録する
ルール テンプレート プロジェクトが正常にコンパイルされ、グローバル アセンブリ キャッシュに入れられたら、その情報を administration.config ファイルに追加し、それを IIS マネージャーに登録する必要があります。
\Windows\System32\inetsrv\config にある administration.config ファイルを開き、次の行を <moduleProviders> セクションに追加します。 PublicKeyToken は必ず置き換えます。
<add name="CanonicalDomainName" type="CanonicalDomainTemplate.CanonicalDomainModuleProvider, CanonicalDomainTemplate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e4e6d0bc8fe7a06a" />
Note
これを moduleProviders の一覧のみに追加すると、このモジュールはサーバー接続の場合にのみ登録されます。 このモジュールをサイト接続とアプリケーション接続でも有効にする場合は、次の一覧に追加します。
<location path=".">
<module>
<add name="CanonicalDomainName" />
</module>
</location>
これらの手順が完了すると、URL Rewrite Module の [Add Rule(s)] (ルールの追加) ダイアログに [Canonical Domain Name] (正規ドメイン名) ルール テンプレートが表示されます。