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

作成者 : Ruslan Yakushev
発行日 : 2008 年 11 月 6 日 (作業者 : ruslany(英語))
更新日 : 2008 年 11 月 10 日 (作業者 : ruslany(英語))

テンプレートの概要

Canonical Domain Name ルール テンプレートを使用すると、Web サイトに標準のドメイン名を強制するために使用する書き換えルールの作成を簡略化できます。ユーザーはこのテンプレートを [Add rule(s)] ダイアログから選択できます。

Dd939065.figu1_template(ja-jp,TechNet.10).gif

ユーザーは、使用するドメイン名を提供できます。

Dd939065.figu2_domainname(ja-jp,TechNet.10).gif

さらに、下記のように、テンプレートで書き換えルールが生成されます。

Dd939065.figu3_append(ja-jp,TechNet.10).gif

前提条件

このチュートリアルを進めるには、IIS マネージャーの拡張性の基本概念について理解するために、記事「How to create a simple IIS Manager module」のタスクを完了することをお勧めします。

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

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

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

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

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

すべてのユーザー インターフェイスの特定の実装は、リモート クライアント コンピューターなどのクライアント側に配置されます。IIS 構成を実際に変更するすべての機能はサーバー側のサービスとして実装されるため、サーバーのすべての構成 API へのアクセス権を持っていることを確認します。クライアント側のコントロールでは、サービス プロキシ経由でサービスと対話します。

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

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

モジュールを作成する

最初に、モジュールを作成する必要があります。すべての拡張性オブジェクトでは、これがクライアントにおける主なエントリ ポイントとなります。これは、次の手順で行ってください。

  1. 記事「How to create a simple IIS Manager module」のタスク 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. [Add rule(s)] ダイアログ ボックスにすべての登録ルール テンプレートを表示する際に使用するために、基本クラスのコンストラクターに名前、タイトル、およびアイコンを渡します。
  3. テンプレート ユーザー インターフェイスをレンダリングするために使用する Run() メソッドを定義します。このメソッドは WinForm ベースのモーダル ダイアログ [CanonicalDomainForm] となります。このダイアログで [OK] ボタンをクリックした場合、Navigate() メソッドを呼び出すことにより、URL 書き換えモジュールのメイン ユーザー インターフェイス ページが更新されます。
  4. 最後に、指定したモジュールのメイン ページを取得するために使用するヘルパー関数 GetPageType を定義します。

サービス プロキシを定義する

リモート クライアントでサービスを呼び出すには、サービス プロキシを提供する必要があります。そのためには、CanonicalDomainModuleServiceProxy.cs というプロジェクトに別のファイルを追加して、そのファイルのコードを下記のように変更します。

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」と入力します。
     Dd939065.figu4_dialog(ja-jp,TechNet.10).gif

  2. Visual Studio の Windows フォーム デザイナーを使用して、フォーム上でコントロールを配置します。
     
    Dd939065.figu5_controls(ja-jp,TechNet.10).gif

  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] ボタンをクリックした場合のイベント ハンドラーを追加します。イベント ハンドラー コードで、TextBox コントロールのコンテンツをパラメーターとして渡して、ヘルパー関数 GenerateRule を呼び出します。

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

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

サービスを実装するには、モジュール プロバイダーを作成する必要があります。モジュール プロバイダーは、IIS マネージャーにおけるモジュールの登録のエントリ ポイントとなります。これは、次の手順で行ってください。

  1. 記事「How to create a simple IIS Manager module」のタスク 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();
        }
    }
}

このコードは、標準のドメインにリダイレクトするためのルールを作成します。

ヒント : 書き換えルールを生成するためのコードをすばやく取得するには、Administration Pack for IIS 7.0 (英語) に含まれている Configuration Editor for IIS 7.0 を使用してください。書き換えルールを作成するためのコードを生成する方法の詳細については、こちらの記事を参照してください。

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" />

注 : moduleProviders のリストだけに追加することにより、モジュールをサーバーの接続情報だけに追加します。このモジュールをサイトの接続情報およびアプリケーションの接続情報でも有効にする場合は、モジュールを次のリストに追加してください。

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

これらの手順を終了すると、URL 書き換えモジュールの [Add Rule(s)] ダイアログで "Canonical Domain Name" ルール テンプレートを参照できるようになります。