開發 URL 重寫模組的規則範本
本逐步解說將引導您開發 URL 重寫課程模組的規則範本。 您將建立可用來產生重寫規則的規則範本,以強制使用網站的特定網域。
範本概觀
標準功能變數名稱規則範本可用來簡化重新撰寫規則的建立,用來強制執行網站的標準功能變數名稱。 使用者可以從 [新增規則 (s) ] 對話方塊選擇此範本:
然後,使用者可以提供他們要使用的功能變數名稱:
之後,範本將產生重寫規則,如下所示:
必要條件
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 和 2 中所述的步驟,從「如何建立簡單的 IIS 管理員模組」一文中建立及設定 Visual Studio 專案。 將專案命名為 「CanonicalDomainTemplateClient」。
- 從 [專案]功能表中選取[新增參考],並將參考新增至位於 \Windows\System32\inetsrv 中的Microsoft.Web.Management.dll:
- 再次選取 [新增參考 ],然後將參考新增至位於 \Program Files\Reference Assemblies\Microsoft\IIS 中的Microsoft.Web.Management.Rewrite.Client.dll。
- 再次選取 [新增參考 ],並將參考新增至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;
}
}
}
此程式碼會執行以下動作:
- 定義規則範本的名稱和標題
- 將名稱、標題和圖示傳遞至基類建構函式,以便在 [新增規則 (s) ] 對話方塊顯示所有已註冊的規則範本時使用
- 定義用來呈現範本使用者介面的 Run () 方法,也就是 WinForm 型強制回應對話方塊 CanonicalDomainForm。 如果在對話方塊中按一下 [確定] 按鈕,則會呼叫 Navigate () 方法來重新整理 URL 重寫模組的主要 UI 頁面。
- 最後,它會定義協助程式函式 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 管理員用戶端管線程式碼都已完成,其餘部分就是設計和實作規則範本的實際使用者介面。 若要這樣做,請遵循下列步驟:
在專案功能表中選取 [新增專案] 選項。 在 [新增專案] 對話方塊中,選取 [Windows Form],然後輸入 CanonicalDomainForm.cs 名稱:
使用 Visual Studio 視窗表單設計工具排列表單上的控制項:
切換至程式碼檢視,並新增類別的私用成員,其中包含服務 Proxy 的參考:
private CanonicalDomainModuleServiceProxy _serviceProxy;
在相同的類別中,修改建構函式程式碼,如下所示:
public CanonicalDomainForm(CanonicalDomainModuleServiceProxy serviceProxy) { _serviceProxy = serviceProxy; InitializeComponent(); }
在相同的類別中,新增協助程式函式,以呼叫服務 Proxy,以使用者指定的參數產生重寫規則:
private void GenerateRule(string domainName) { try { _serviceProxy.GenerateRule(domainName); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
按一下 [確定] 按鈕時,新增 的事件處理常式。 在事件處理常式程式碼中,叫用 Helper 函式 GenerateRule,將 TextBox 控制項的內容傳遞為參數。
private void OnOkButtonClick(object sender, EventArgs e) { GenerateRule(_DomainTextBox.Text); }
實作規則範本的服務
若要實作服務,您必須建立模組提供者,這是在 IIS 管理員中註冊模組的進入點。 若要這樣做:
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」。
從[專案]功能表中選取[新增參考],並將參考新增至位於 \Windows\System32\inetsrv 的下列元件:
- Microsoft.Web.Administration.dll
- Microsoft.Web.Management.dll
從 [專案] 功能表中選取 [ 新增專案 ] 選項。 在 [ 新增專案 ] 對話方塊中,選取 [類別 ] 範本,然後輸入 CanonicalDomainModuleProvider.cs 作為檔案名。
變更程式碼,使其看起來如下 (別忘了以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 類型。
若要建立規則範本的服務,請遵循下列步驟:
- 選取 [專案] 功能表中的 [新增專案] 選項。 選取 [類別] 範本,然後輸入 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 和更新版本設定編輯器,其中包含于 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 重寫模組的 [新增規則] ([) ] 對話方塊中看到「標準功能變數名稱」規則範本。