Entwickeln einer Regelvorlage für das URL-Rewrite-Modul

von Ruslan Yakushev

In dieser exemplarischen Vorgehensweise werden die Schritte zur Entwicklung einer Regelvorlage für das URL-Rewrite-Modul beschrieben. Sie erstellen eine Regelvorlage, die zum Generieren einer Umschreibungsregel verwendet werden kann, die die Verwendung einer bestimmten Domäne für eine Website erzwingt.

Übersicht über die Vorlage

Die Regelvorlage „Kanonischer Domänenname“ vereinfacht die Erstellung einer Umschreibungsregel, die zum Erzwingen kanonischer Domänennamen für eine Website verwendet wird. Benutzer und Benutzerinnen können diese Vorlage im Dialogfeld „Regeln hinzufügen“ auswählen:

Screenshot of Add rule(s) dialog with

Anschließend können sie den gewünschten Domänennamen angeben:

Screenshot of

Danach generiert die Vorlage wie folgt eine Umschreibungsregel:

Screenshot of Edit Rule pane with sections for domain Name, URL, Conditions, and Action.

Voraussetzungen

Bevor Sie mit dieser exemplarischen Vorgehensweise fortfahren, sollten Sie sich mit den grundlegenden Konzepten der Erweiterbarkeit von IIS-Manager vertraut machen, indem Sie die Aufgaben im Artikel Erstellen eines einfachen IIS-Manager-Moduls ausführen.

VS2008-Projekt für die Regelvorlage

Das vollständige Visual Studio 2008-Projekt für diese Regelvorlage steht hier zum Download zur Verfügung.

Implementieren einer Regelvorlage

Zur Unterstützung der Remoteverwaltung werden alle Benutzeroberflächenkomponenten von IIS-Manager mithilfe eines spezifischen Entwurfsmusters implementiert. Die Implementierung eines Moduls umfasst die folgenden Teile:

  • Clientseitige Benutzeroberfläche und Dienstproxy
  • Serverseitiger Dienst zum Verwalten der IIS-Konfiguration

Die gesamte benutzeroberflächenspezifische Implementierung erfolgt auf dem Client, bei dem es sich auch um einen Remoteclientcomputer handeln kann. Alle Funktionen, die tatsächlich Änderungen an der IIS-Konfiguration vornehmen, werden serverseitig als Dienst implementiert. Damit wird sichergestellt, dass sie Zugriff auf alle Serverkonfigurations-APIs haben. Clientseitige Steuerelemente interagieren über einen Dienstproxy mit dem Dienst.

Es empfiehlt sich, Regelvorlagen mithilfe desselben Musters zu implementieren, damit die Vorlagen funktionieren, wenn Regeln über IIS-Remote-Manager erstellt werden. In den folgenden Abschnitten wird beschrieben, wie Regelvorlagendienst und -client implementiert werden.

Implementieren einer clientseitigen Benutzeroberfläche

Erstellen eines Moduls

Sie müssen zuerst ein Modul erstellen. Dies ist der Haupteinstiegspunkt auf dem Client für alle Erweiterbarkeitsobjekte. Gehen Sie dafür folgendermaßen vor:

  1. Erstellen und konfigurieren Sie ein Visual Studio-Projekt, indem Sie die im Artikel Erstellen eines einfachen IIS-Manager-Moduls in den Aufgaben 1 und 2 beschriebenen Schritte ausführen. Benennen Sie das Projekt mit „CanonicalDomainTemplateClient“.
  2. Wählen Sie Verweise hinzufügen im Menü Projekt aus, und fügen Sie Verweise auf „Microsoft.Web.Management.dll“ unter „\Windows\System32\inetsrv“ hinzu:
  3. Wählen Sie erneut Verweis hinzufügen aus, und fügen Sie einen Verweis auf „Microsoft.Web.Management.Rewrite.Client.dll“ in „\Programme\Reference Assemblys\Microsoft\IIS“ hinzu.
  4. Wählen Sie erneut Verweis hinzufügen aus, und fügen Sie einen Verweis auf „System.Windows.Forms.dll“ hinzu.
  5. Wählen Sie im Menü „Projekt“ die Option Neues Element hinzufügen aus. Wählen Sie im Dialogfeld Neues Element hinzufügen die Vorlage Klasse aus, und geben Sie als Namen für die Datei „CanonicalDomainModule.cs“ ein.
  6. Ändern Sie den Code so, dass er wie folgt aussieht:
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)); 
        }
    }
}

Dieser Code initialisiert eine neue Instanz einer CanonicalDomainFeature-Klasse, die die Regelvorlagenfunktionalität implementiert. Mit der Instanz dieser Klasse wird eine Erweiterung des Typs RewriteTemplateFeature registriert. Dabei handelt es sich um einen Typ, von dem alle Regelvorlagen abgeleitet werden.

Erstellen eines Feature für eine Umschreibungsregel

Beim Definieren einer Klasse, die eine Regelvorlage implementiert, müssen Sie diese Klasse von der RewriteTemplateFeature-Klasse ableiten. Es handelt sich um eine übergeordnete Klasse, die von allen URL-Rewrite-Regelvorlagen verwendet wird.

  1. Wählen Sie im Menü „Projekt“ die Option „Neues Element hinzufügen“ aus. Wählen Sie die Vorlage „Klasse“ aus, und geben Sie als Dateinamen „CanonicalDomainFeature.cs“ ein.
  2. Ändern Sie den Code so, dass er wie folgt aussieht:
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;
        }
    }
}

Dieser Code bewirkt Folgendes:

  1. Definiert den Namen und Titel für die Regelvorlage
  2. Übergibt den Namen, den Titel und die Symbole an den Basisklassenkonstruktor, sodass diese verwendet werden, wenn im Dialogfeld „Regeln hinzufügen“ alle registrierten Regelvorlagen angezeigt werden
  3. Definiert die Run()-Methode, die zum Rendern der Benutzeroberfläche der Vorlage verwendet wird. Dabei handelt es sich um ein modales WinForm-Dialogfeld (CanonicalDomainForm). Wenn im Dialogfeld die Schaltfläche „OK“ ausgewählt wird, wird die Hauptbenutzeroberfläche des URL-Rewrite-Moduls durch Aufrufen der Navigate()-Methode aktualisiert.
  4. Abschließend definiert sie die Hilfsfunktion GetPageType, die zum Abrufen der Hauptseite für das angegebene Modul verwendet wird.

Definieren eines Dienstproxys

Damit ein Remoteclient einen Dienst aufrufen kann, muss ein Dienstproxy bereitgestellt werden. Fügen Sie dazu Ihrem Projekt eine weitere Datei namens „CanonicalDomainModuleServiceProxy.cs“ hinzu, und ändern Sie den Darin enthaltenen Code wie folgt:

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);
        }
    }
}

Die tatsächliche Dienstimplementierung für die GenerateRule-Methode wird später hinzugefügt.

Implementieren des Dialogfelds „Regelvorlage“

Nachdem nun der gesamte clientseitige Code von IIS-Manager ausgeführt wird, entwerfen und implementieren Sie im verbleibenden Teil die eigentliche Benutzeroberfläche für die Regelvorlage. Führen Sie dazu die folgenden Schritte aus:

  1. Wählen Sie im Menü „Projekt“ die Option „Neues Element hinzufügen“ aus. Wählen Sie im Dialogfeld „Neues Element hinzufügen“ die Option „Windows Forms“ aus, und geben Sie den Namen „CanonicalDomainForm.cs“ ein:
    Screenshot of Add New Item dialog with a Windows Form template selected.

  2. Verwenden Sie den Windows Forms-Designer von Visual Studio, um die Steuerelemente im Formular anzuordnen:
    Screenshot of the new form in Visual Studio windows form designer.

  3. Wechseln Sie zur Codeansicht, und fügen Sie den privaten Member der Klasse hinzu, der einen Verweis auf einen Dienstproxy enthält:

    private CanonicalDomainModuleServiceProxy _serviceProxy;
    
  4. Ändern Sie in derselben Klasse den Konstruktorcode wie folgt:

    public CanonicalDomainForm(CanonicalDomainModuleServiceProxy serviceProxy)
    {
       _serviceProxy = serviceProxy;
       InitializeComponent();
    }
    
  5. Fügen Sie in derselben Klasse die Hilfsfunktion hinzu, die den Dienstproxy aufruft, um die Umschreibungsregel mit den benutzerseitig angegebenen Parametern zu generieren:

    private void GenerateRule(string domainName)
    {
        try
        {
            _serviceProxy.GenerateRule(domainName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    
  6. Fügen Sie einen Ereignishandler für die Auswahl der Schaltfläche „OK“ hinzu. Rufen Sie im Ereignishandlercode die Hilfsfunktion „GenerateRule“ auf, und übergeben Sie den Inhalt des TextBox-Steuerelements als Parameter.

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

Implementieren eines Diensts für die Regelvorlage

Um einen Dienst zu implementieren, müssen Sie einen Modulanbieter erstellen, der als Einstiegspunkt für die Registrierung von Modulen in IIS-Manager fungiert. Gehen Sie dafür folgendermaßen vor:

  1. Erstellen und konfigurieren Sie ein weiteres Visual Studio-Projekt, indem Sie die im Artikel Erstellen eines einfachen IIS-Manager-Moduls in den Aufgaben 1 und 2 beschriebenen Schritte ausführen. Benennen Sie das Projekt mit „CanonicalDomainTemplate“.

  2. Wählen Sie im MenüProjekt die Option Verweise hinzufügen aus, und fügen Sie Verweise auf die folgenden Assemblys in „\Windows\System32\inetsrv“ hinzu:

    1. Microsoft.Web.Administration.dll
    2. Microsoft.Web.Management.dll
  3. Wählen Sie im Menü „Projekt“ die Option Neues Element hinzufügen aus. Wählen Sie im Dialogfeld Neues Element hinzufügen die Vorlage Klasse aus, und geben Sie als Namen für die Datei „CanonicalDomainModuleProvider.cs“ ein.

  4. Ändern Sie den Code so, dass er wie unten aussieht (vergessen Sie nicht, das PublicKeyToken durch das Token mit öffentlichem Schlüssel der Assembly „CanonicalDomainTemplate.Client.dll“ zu ersetzen).

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;
        }
    }
}

Dieser Code erstellt einen ModuleProvider, der alle Typen von Verbindungen (Server, Website und Anwendung) unterstützt und ein clientseitiges Modul namens CanonicalDomainModule registriert. Außerdem wird der Typ des Moduldiensts CanonicalDomainModuleService registriert, der auf dem Server zum Generieren von Umschreibungsregeln verwendet wird.

Führen Sie die folgenden Schritte aus, um einen Dienst für die Regelvorlage zu erstellen:

  1. Wählen Sie im Menü „Projekt“ die Option „Neues Element hinzufügen“ aus. Wählen Sie die Vorlage „Klasse“ aus, und geben Sie als Dateinamen „CanonicalDomainModuleService.cs“ ein.
  2. Ändern Sie den Code so, dass er wie folgt aussieht:
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();
        }
    }
}

Dieser Code erstellt eine Regel für die Umleitung zur kanonischen Domäne.

Tipp

Um den Code zum Generieren von Umschreibungsregeln schnell zu erhalten, verwenden Sie den Konfigurations-Editor für IIS 7.0 und höher, der im Administration Pack für IIS enthalten ist. Weitere Informationen zum Generieren von Code zum Erstellen von Umschreibungsregeln finden Sie in diesem Artikel.

Registrieren der Regelvorlage bei IIS-Manager

Nachdem das Regelvorlagenprojekt erfolgreich kompiliert und im globalen Assemblycache gespeichert wurde, müssen Sie es bei IIS-Manager registrieren, indem Sie die zugehörigen Informationen in der Datei „administration.config“ hinzufügen.

Öffnen Sie die Datei „administration.config“ in „\Windows\System32\inetsrv\config“, und fügen Sie im Abschnitt <moduleProviders> die folgende Zeile ein. Achten Sie darauf, das PublicKeyToken zu ersetzen:

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

Hinweis

Indem Sie es nur der Liste „moduleProviders“ hinzufügen, registrieren Sie das Modul nur für Serververbindungen. Wenn dieses Modul für Website- und Anwendungsverbindungen aktiviert werden soll, fügen Sie es der folgenden Liste hinzu:

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

Nachdem diese Schritte ausgeführt wurden, sollte die Regelvorlage „Kanonischer Domänenname“ im Dialogfeld „Regel hinzufügen“ des URL-Rewrite-Moduls angezeigt werden.