Modèle de règle de développement pour le module de réécriture d’URL

par Ruslan Yakushev

Cette procédure pas à pas vous guide tout au long du développement d’un modèle de règle pour le module réécriture d’URL. Vous allez créer un modèle de règle qui peut être utilisé pour générer une règle de réécriture qui applique l’utilisation d’un domaine particulier pour un site web.

Présentation des modèles

Le modèle de règle de nom de domaine canonique peut être utilisé pour simplifier la création d’une règle de réécriture utilisée pour appliquer le nom de domaine canonique d’un site web. Les utilisateurs peuvent choisir ce modèle dans la boîte de dialogue « Ajouter des règles » :

Screenshot of Add rule(s) dialog with

Les utilisateurs peuvent ensuite fournir un nom de domaine qu’ils souhaitent utiliser :

Screenshot of

Après cela, le modèle génère une règle de réécriture comme suit :

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

Prérequis

Avant de passer à cette procédure pas à pas, il est recommandé de vous familiariser avec les concepts de base de l’extensibilité du Gestionnaire IIS en effectuant les tâches de l’article « Comment créer un module gestionnaire IIS simple ».

Projet VS2008 pour le modèle de règle

Le projet Visual Studio 2008 complet pour ce modèle de règle est disponible pour le téléchargement ici.

Implémentation d’un modèle de règle

Pour prendre en charge la gestion à distance, tous les composants de l’interface utilisateur du Gestionnaire IIS sont implémentés en suivant un certain modèle de conception. L’implémentation d’un module se compose de ces parties :

  • Interface utilisateur côté client et proxy de service
  • Service côté serveur pour la gestion de la configuration IIS

Toute l’implémentation spécifique de l’interface utilisateur réside côté client, qui peut être une machine cliente distante. Toutes les fonctionnalités qui modifient réellement la configuration IIS sont implémentées en tant que service côté serveur, ce qui garantit qu’elle a accès à toutes les API de configuration de serveur. Les contrôles côté client interagissent avec le service via le proxy de service.

Il est recommandé d’implémenter des modèles de règles en suivant le même modèle, afin que les modèles fonctionnent lorsque les utilisateurs créent des règles via le Gestionnaire distant IIS. Les sections suivantes décrivent comment implémenter le service de modèle de règle et le client.

Implémentation d’une interface utilisateur côté client

Création d’un module

Tout d’abord, vous devez créer un module, est le point d’entrée principal du client pour tous les objets d’extensibilité. Pour ce faire :

  1. Créez et configurez un projet Visual Studio en suivant les étapes décrites dans les tâches 1 et 2 de l’article «Comment créer un module gestionnaire IIS simple». Nommez le projet en tant que « CanonicalDomainTemplateClient ».
  2. Sélectionnez Ajouter des références dans le menu Projet et ajoutez des références à Microsoft.Web.Management.dll situées dans \Windows\System32\inetsrv :
  3. Sélectionnez Ajouter une référence à nouveau et ajoutez une référence à Microsoft.Web.Management.Rewrite.Client.dll située dans \Program Files\Reference Assemblys\Microsoft\IIS.
  4. Sélectionnez à nouveau Ajouter une référence et ajoutez une référence à System.Windows.Forms.dll
  5. Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Dans la boîte de dialogue Ajouter un nouvel élément , sélectionnez le modèle Classe et tapez CanonicalDomainModule.cs comme nom du fichier.
  6. Modifiez le code pour qu’il ressemble à ce qui suit :
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)); 
        }
    }
}

Ce code initialise une nouvelle instance d’une classe CanonicalDomainFeature, qui implémente la fonctionnalité de modèle de règle. L’instance de cette classe est utilisée pour inscrire une extension de type RewriteTemplateFeature, qui est un type à partir duquel tous les modèles de règle sont dérivés.

Créer une fonctionnalité de modèle de réécriture

Lors de la définition d’une classe qui implémente un modèle de règle, vous devez dériver cette classe de la classe RewriteTemplateFeature. Il s’agit d’une classe parente utilisée par tous les modèles de règle de réécriture d’URL.

  1. Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Sélectionnez le modèle de classe et tapez CanonicalDomainFeature.cs comme nom de fichier.
  2. Modifiez le code pour qu’il ressemble à ce qui suit :
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;
        }
    }
}

Ce code effectue ce qui suit :

  1. Définit le nom et le titre du modèle de règle
  2. Transmet le nom, le titre et les icônes au constructeur de classe de base afin que ceux-ci soient utilisés lorsque la boîte de dialogue « Ajouter des règles » affiche tous les modèles de règles inscrits
  3. Définit la méthode Run() utilisée pour afficher l’interface utilisateur du modèle, qui est la boîte de dialogue modale basée sur WinForm CanonicalDomainForm. Si le bouton OK est cliqué dans la boîte de dialogue, la page principale de l’interface utilisateur du module réécriture d’URL est actualisée en appelant la méthode Navigate().
  4. Enfin, il définit une fonction d’assistance GetPageType utilisée pour obtenir la page principale du module spécifié.

Définir un proxy de service

Pour qu’un client distant appelle un service, il est nécessaire de fournir un proxy de service. Pour ce faire, ajoutez un autre fichier à votre projet appelé CanonicalDomainModuleServiceProxy.cs et modifiez le code dans celui-ci pour qu’il se présente comme suit :

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

L’implémentation de service réelle pour la méthode GenerateRule sera ajoutée ultérieurement.

Boîte de dialogue Implémenter le modèle de règle

Maintenant que tout le code de plomberie côté client du Gestionnaire IIS est terminé, la partie restante consiste à concevoir et à implémenter l’interface utilisateur réelle pour le modèle de règle. Pour ce faire, procédez comme suit :

  1. Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez « Windows Form » et tapez le nom CanonicalDomainForm.cs :
    Screenshot of Add New Item dialog with a Windows Form template selected.

  2. Utilisez le concepteur Windows Forms Visual Studio pour organiser des contrôles sur le formulaire :
    Screenshot of the new form in Visual Studio windows form designer.

  3. Basculez vers la vue de code et ajoutez le membre privé de la classe qui contiendra une référence à un proxy de service :

    private CanonicalDomainModuleServiceProxy _serviceProxy;
    
  4. Dans la même classe, modifiez le code du constructeur comme indiqué ci-dessous :

    public CanonicalDomainForm(CanonicalDomainModuleServiceProxy serviceProxy)
    {
       _serviceProxy = serviceProxy;
       InitializeComponent();
    }
    
  5. Dans la même classe, ajoutez la fonction d’assistance qui appellera le proxy de service pour générer la règle de réécriture avec les paramètres spécifiés par un utilisateur :

    private void GenerateRule(string domainName)
    {
        try
        {
            _serviceProxy.GenerateRule(domainName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    
  6. Ajoutez un gestionnaire d’événements lorsque le bouton OK est cliqué. Dans le code du gestionnaire d’événements, appelez la fonction d’assistance GenerateRule, en passant le contenu du contrôle TextBox en tant que paramètre.

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

Implémentation d’un service pour le modèle de règle

Pour implémenter un service, vous devez créer un fournisseur de modules, qui est un point d’entrée pour l’inscription de modules dans le Gestionnaire IIS. Pour ce faire :

  1. Créez et configurez un autre projet Visual Studio en suivant les étapes décrites dans les tâches 1 et 2 de l’article «Comment créer un module gestionnaire IIS simple». Nommez le projet en tant que « CanonicalDomainTemplate ».

  2. Sélectionnez Ajouter des références dans le menu Projet et ajoutez des références aux assemblys suivants situés dans \Windows\System32\inetsrv :

    1. Microsoft.Web.Administration.dll
    2. Microsoft.Web.Management.dll
  3. Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez le modèle de classe et tapez CanonicalDomainModuleProvider.cs comme nom du fichier.

  4. Modifiez le code afin qu’il ressemble à ce qui suit (n’oubliez pas de remplacer publicKeyToken par le jeton de clé publique de l’assembly 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;
        }
    }
}

Ce code crée un ModuleProvider qui prend en charge tous les types de connexions (serveur, site et application) et inscrit un module côté client appelé CanonicalDomainModule. Il inscrit également le type du service de module CanonicalDomainModuleService utilisé côté serveur pour générer des règles de réécriture.

Pour créer un service pour le modèle de règle, procédez comme suit :

  1. Sélectionnez l’option Ajouter un nouvel élément dans le menu Projet. Sélectionnez le modèle de classe et tapez CanonicalDomainModuleService.cs comme nom de fichier.
  2. Modifiez le code pour qu’il ressemble à ce qui suit :
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();
        }
    }
}

Ce code crée une règle pour la redirection vers un domaine canonique.

Conseil

pour obtenir rapidement le code permettant de générer des règles de réécriture, utilisez l’Éditeur de configuration pour IIS 7.0 et versions ultérieures, qui est inclus dans Pack d’administration pour IIS. Reportez-vous à cet article pour plus d’informations sur la façon de générer du code pour la création de règles de réécriture.

Inscription du modèle de règle auprès du Gestionnaire IIS

Une fois le projet de modèle de règle compilé et placé dans le Global Assembly Cache, vous devez l’inscrire auprès du Gestionnaire IIS en ajoutant ses informations au fichier administration.config.

Ouvrez le fichier administration.config situé dans \Windows\System32\inetsrv\config et ajoutez la ligne suivante à la section <moduleProviders>. Veillez à remplacer PublicKeyToken :

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

Remarque

En l’ajoutant uniquement à la liste des modulesProviders que vous inscrivez le module uniquement pour les connexions serveur. Si vous souhaitez que ce module soit activé pour les connexions de site ainsi que pour les connexions d’application, ajoutez-le à la liste suivante :

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

Une fois ces étapes effectuées, vous devez être en mesure de voir le modèle de règle « Nom de domaine canonique » dans la boîte de dialogue Ajouter une ou plusieurs règles de réécriture d’URL.