次の方法で共有


URL 書き換えモジュールのルール テンプレートの開発

Ruslan Yakushev

このチュートリアルでは、URL 書き換えモジュールのルール テンプレートを開発する方法について説明します。 Web サイトの特定のドメインの使用を強制する書き換えルールを生成するために使用できるルール テンプレートを作成します。

テンプレートの概要

正規ドメイン名ルール テンプレートを使用すると、Web サイトに正規ドメイン名を適用するために使用される書き換えルールの作成を簡略化できます。 ユーザーは、[ルールの追加] ダイアログからこのテンプレートを選択できます。

[標準ドメイン名] が選択されている [ルールの追加] ダイアログのスクリーンショット。

その後、ユーザーは使用するドメイン名を指定できます。

[正規ドメイン名] ダイアログで指定された

その後、テンプレートは次のように書き換えルールを生成します。

ドメイン名、URL、条件、およびアクションのセクションを含む [ルールの編集] ウィンドウのスクリーンショット。

前提条件

このチュートリアルを進める前に、「単純な IIS マネージャー モジュールを作成する方法」の記事のタスクを完了して、IIS マネージャーの拡張機能の基本的な概念を理解しておくことをお勧めします。

ルール テンプレートの VS2008 プロジェクト

このルール テンプレートの完全な Visual Studio 2008 プロジェクトは、 ここからダウンロードできます。

ルール テンプレートの実装

リモート管理をサポートするために、すべての IIS マネージャー UI コンポーネントは、特定の設計パターンに従って実装されます。 モジュールの実装は、次の部分で構成されます。

  • クライアント側のユーザー インターフェイスとサービス プロキシ
  • IIS 構成を管理するためのサーバー側サービス

すべてのユーザー インターフェイス固有の実装は、リモート クライアント コンピューターである可能性があるクライアント側に存在します。 IIS 構成に実際に変更を加えるすべての機能は、サーバー側のサービスとして実装されるため、すべてのサーバー構成 API に確実にアクセスできます。 クライアント側コントロールは、サービス プロキシを介してサービスと対話します。

ユーザーが IIS リモート マネージャーを使用してルールを作成するときにテンプレートが機能するように、同じパターンに従ってルール テンプレートを実装することをお勧めします。 次のセクションでは、ルール テンプレート サービスとクライアントを実装する方法について説明します。

クライアント側ユーザー インターフェイスの実装

モジュールを作成する

まず、モジュールを作成する必要があります。これは、すべての拡張オブジェクトのクライアントのメイン エントリ ポイントです。 その手順を次に示します。

  1. 簡単な IIS マネージャー モジュールを作成する方法」のタスク 1 と 2 で説明されている手順に従って、Visual Studio プロジェクトを作成して構成します。 プロジェクトに "CanonicalDomainTemplateClient" という名前を付けます。
  2. [プロジェクト] メニューから [参照の追加] を選択し、\Windows\System32\inetsrv にある Microsoft.Web.Management.dll への参照を追加します。
  3. もう一度 [ 参照の追加] を選択し、\Program Files\Reference Assemblies\Microsoft\IIS にある Microsoft.Web.Management.Rewrite.Client.dll への参照を追加します。
  4. [ 参照の追加] をもう一度選択し、System.Windows.Forms.dll への参照を追加します
  5. [プロジェクト] メニューから [ 新しい項目の追加 ] オプションを選択します。 [ 新しい項目の追加 ] ダイアログ ボックスで、 クラス テンプレートを選択し、ファイルの名前として「CanonicalDomainModule.cs」と入力します。
  6. 次のようにコードを変更します。
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 書き換えルール テンプレートで使用される親クラスです。

  1. [プロジェクト] メニューの [新しい項目の追加] オプションを選択します。 [クラス] テンプレートを選択し、ファイル名として「CanonicalDomainFeature.cs」と入力します。
  2. 次のようにコードを変更します。
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;
        }
    }
}

このコードでは、次の処理が行われます。

  1. ルール テンプレートの名前とタイトルを定義します
  2. 名前、タイトル、アイコンを基底クラスのコンストラクターに渡し、"ルールの追加" ダイアログに登録済みのすべてのルール テンプレートが表示されるときに使用されるようにします。
  3. テンプレート ユーザー インターフェイスのレンダリングに使用される Run() メソッドを定義します。これは、WinForm ベースのモーダル ダイアログ CanonicalDomainForm です。 ダイアログで [OK] ボタンをクリックすると、Navigate() メソッドを呼び出すことによって、URL 書き換えモジュールのメイン UI ページが更新されます。
  4. 最後に、指定したモジュールのメイン ページを取得するために使用されるヘルパー関数 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 マネージャーのクライアント側のプラミング コードがすべて完了しました。残りの部分は、ルール テンプレートの実際のユーザー インターフェイスを設計して実装することです。 これを行うには、次の手順に従います。

  1. プロジェクト メニューの [新しい項目の追加] オプションを選択します。 [新しい項目の追加] ダイアログで、[Windows フォーム] を選択し、CanonicalDomainForm.cs名前を入力します。
    Windows フォーム テンプレートが選択されている [新しい項目の追加] ダイアログのスクリーンショット。

  2. Visual Studio ウィンドウ フォーム デザイナーを使用して、フォームにコントロールを配置します。
    Visual Studio ウィンドウ フォーム デザイナーの新しいフォームのスクリーンショット。

  3. コード ビューに切り替え、サービス プロキシへの参照を含むクラスのプライベート メンバーを追加します。

    private CanonicalDomainModuleServiceProxy _serviceProxy;
    
  4. 同じクラスで、次のようにコンストラクター コードを変更します。

    public CanonicalDomainForm(CanonicalDomainModuleServiceProxy serviceProxy)
    {
       _serviceProxy = serviceProxy;
       InitializeComponent();
    }
    
  5. 同じクラスで、サービス プロキシを呼び出して、ユーザーが指定したパラメーターを使用して書き換えルールを生成するヘルパー関数を追加します。

    private void GenerateRule(string domainName)
    {
        try
        {
            _serviceProxy.GenerateRule(domainName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    
  6. [OK] ボタンがクリックされたときにイベント ハンドラーを追加します。 イベント ハンドラー コードでヘルパー関数 GenerateRule を呼び出し、TextBox コントロールの内容をパラメーターとして渡します。

    private void OnOkButtonClick(object sender, EventArgs e)
    {
        GenerateRule(_DomainTextBox.Text);
    }
    

ルール テンプレートのサービスの実装

サービスを実装するには、IIS マネージャーでモジュールを登録するためのエントリ ポイントであるモジュール プロバイダーを作成する必要があります。 その手順を次に示します。

  1. 簡単な IIS マネージャー モジュールを作成する方法」の記事のタスク 1 と 2 で説明されている手順に従って、別の Visual Studio プロジェクトを作成して構成します。 プロジェクトに "CanonicalDomainTemplate" という名前を付けます。

  2. [プロジェクト] メニューから [参照の追加] を選択し、\Windows\System32\inetsrv にある次のアセンブリへの参照を追加します。

    1. Microsoft.Web.Administration.dll
    2. Microsoft.Web.Management.dll
  3. [プロジェクト] メニューから [ 新しい項目の追加 ] オプションを選択します。 [ 新しい項目の追加 ] ダイアログ ボックスで、 クラス テンプレートを選択し、ファイルの名前として「CanonicalDomainModuleProvider.cs」と入力します。

  4. 次のようにコードを変更します (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 の型も登録します。

ルール テンプレートのサービスを作成するには、次の手順に従います。

  1. [プロジェクト] メニューの [新しい項目の追加] オプションを選択します。 クラス テンプレートを選択し、ファイル名として「CanonicalDomainModuleService.cs」と入力します。
  2. 次のようにコードを変更します。
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 用 管理パックに含まれている IIS 7.0 以降の構成エディターを使用します。 書き換えルールを作成するためのコードを生成する方法の詳細については、 この記事 を参照してください。

ルール テンプレートを IIS マネージャーに登録する

ルール テンプレート プロジェクトが正常にコンパイルされ、グローバル アセンブリ キャッシュに配置されたら、その情報をファイルに追加して IIS マネージャーに登録 administration.config 必要があります。

\Windows\System32\inetsrv\config にあるファイル administration.config 開き、 <moduleProviders> セクションに次の行を追加します。 PublicKeyToken を必ず置き換えてください。

<add name="CanonicalDomainName" type="CanonicalDomainTemplate.CanonicalDomainModuleProvider, CanonicalDomainTemplate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e4e6d0bc8fe7a06a" />

モジュールを moduleProviders の一覧にのみ追加することで、モジュールをサーバー接続にのみ登録します。 このモジュールをサイト接続とアプリケーション接続に対して有効にする場合は、次の一覧に追加します。

<location path=".">
   <module> 
     <add name="CanonicalDomainName" />
   </module>
</location>

これらの手順が完了すると、URL 書き換えモジュールの [ルールの追加] ダイアログに "標準ドメイン名" ルール テンプレートが表示されます。