共用方式為


開發 URL 重寫模組的規則範本

作者 :Ruslan Yakushev

本逐步解說將引導您開發 URL 重寫課程模組的規則範本。 您將建立可用來產生重寫規則的規則範本,以強制使用網站的特定網域。

範本概觀

標準功能變數名稱規則範本可用來簡化重新撰寫規則的建立,用來強制執行網站的標準功能變數名稱。 使用者可以從 [新增規則 (s) ] 對話方塊選擇此範本:

[新增規則] ([) ] 對話方塊的螢幕擷取畫面,其中已選取 [標準功能變數名稱]。

然後,使用者可以提供他們要使用的功能變數名稱:

[標準功能變數名稱] 對話方塊中所指定 「www.mysite.com」的螢幕擷取畫面。

之後,範本將產生重寫規則,如下所示:

[編輯規則] 窗格的螢幕擷取畫面,其中包含功能變數名稱、URL、條件和動作的區段。

必要條件

Before proceeding with this walkthrough it is recommended to familiarize yourself with the basic concepts of IIS Manager extensibility by completing the tasks in the article "How to create a simple IIS Manager module".

規則範本的 VS2008 專案

此規則範本的完整 Visual Studio 2008 專案可供 在這裡下載。

實作規則範本

為了支援遠端系統管理,所有 IIS 管理員 UI 元件都是透過遵循特定設計模式來實作。 模組的實作包含下列部分:

  • 用戶端使用者介面和服務 Proxy
  • 用於管理 IIS 組態的伺服器端服務

所有使用者介面特定實作都位於用戶端,可能是遠端用戶端電腦。 實際對 IIS 組態進行變更的所有功能都會在伺服器端實作為服務,因此確保它可以存取所有伺服器組態 API。 用戶端控制項會透過服務 Proxy 與服務互動。

最佳做法是遵循相同的模式來實作規則範本,以便範本在使用者透過 IIS 遠端系統管理員建立規則時運作。 下列各節說明如何實作規則範本服務和用戶端。

實作用戶端使用者介面

建立模組

首先,您必須建立模組,這是用戶端中所有擴充性物件的主要進入點。 若要這樣做:

  1. 遵循工作 1 和 2 中所述的步驟,從「如何建立簡單的 IIS 管理員模組」一文中建立及設定 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. 將名稱、標題和圖示傳遞至基類建構函式,以便在 [新增規則 (s) ] 對話方塊顯示所有已註冊的規則範本時使用
  3. 定義用來呈現範本使用者介面的 Run () 方法,也就是 WinForm 型強制回應對話方塊 CanonicalDomainForm。 如果在對話方塊中按一下 [確定] 按鈕,則會呼叫 Navigate () 方法來重新整理 URL 重寫模組的主要 UI 頁面。
  4. 最後,它會定義協助程式函式 GetPageType ,用來取得指定模組的主頁面。

定義服務 Proxy

若要讓遠端用戶端呼叫服務,您必須提供服務 Proxy。 若要這樣做,請將另一個檔案新增至名為 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 Form],然後輸入 CanonicalDomainForm.cs 名稱:
    [新增專案] 對話方塊的螢幕擷取畫面,其中已選取 Windows Form 範本。

  2. 使用 Visual Studio 視窗表單設計工具排列表單上的控制項:
    Visual Studio 視窗表單設計工具中新表單的螢幕擷取畫面。

  3. 切換至程式碼檢視,並新增類別的私用成員,其中包含服務 Proxy 的參考:

    private CanonicalDomainModuleServiceProxy _serviceProxy;
    
  4. 在相同的類別中,修改建構函式程式碼,如下所示:

    public CanonicalDomainForm(CanonicalDomainModuleServiceProxy serviceProxy)
    {
       _serviceProxy = serviceProxy;
       InitializeComponent();
    }
    
  5. 在相同的類別中,新增協助程式函式,以呼叫服務 Proxy,以使用者指定的參數產生重寫規則:

    private void GenerateRule(string domainName)
    {
        try
        {
            _serviceProxy.GenerateRule(domainName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    
  6. 按一下 [確定] 按鈕時,新增 的事件處理常式。 在事件處理常式程式碼中,叫用 Helper 函式 GenerateRule,將 TextBox 控制項的內容傳遞為參數。

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

實作規則範本的服務

若要實作服務,您必須建立模組提供者,這是在 IIS 管理員中註冊模組的進入點。 若要這樣做:

  1. Create and configure another Visual Studio project by following steps described in tasks 1 and 2 from the article "How to create a simple IIS Manager module". 將專案命名為 「CanonicalDomainTemplate」。

  2. [專案]功能表中選取[新增參考],並將參考新增至位於 \Windows\System32\inetsrv 的下列元件:

    1. Microsoft.Web.Administration.dll
    2. Microsoft.Web.Management.dll
  3. 從 [專案] 功能表中選取 [ 新增專案 ] 選項。 在 [ 新增專案 ] 對話方塊中,選取 [類別 ] 範本,然後輸入 CanonicalDomainModuleProvider.cs 作為檔案名。

  4. 變更程式碼,使其看起來如下 (別忘了以CanonicalDomainTemplate.Client.dll元件的公開金鑰權杖取代 PublicKeyToken)

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 7.0 和更新版本設定編輯器,其中包含于 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" />

注意

只要將它新增至您註冊模組的 moduleProviders 清單,就只會針對伺服器連線註冊模組。 如果您想要針對月臺連線和應用程式連線啟用此模組,請將它新增至下列清單:

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

完成這些步驟之後,您應該可以在 URL 重寫模組的 [新增規則] ([) ] 對話方塊中看到「標準功能變數名稱」規則範本。