Sviluppo di un modello di regola per il modulo di riscrittura URL

di Ruslan Kashšev

Questa procedura dettagliata illustra come sviluppare un modello di regola per il modulo di riscrittura URL. Verrà creato un modello di regola che può essere usato per generare una regola di riscrittura che impone l'utilizzo di un dominio specifico per un sito Web.

Panoramica del modello

Il modello di regola Nome dominio canonico può essere usato per semplificare la creazione di una regola di riscrittura usata per applicare il nome di dominio canonico per un sito Web. Gli utenti possono scegliere questo modello dalla finestra di dialogo "Aggiungi regole":

Screenshot della finestra di dialogo Aggiungi regole con l'opzione

Gli utenti possono quindi specificare un nome di dominio che vogliono usare:

Screenshot di

Successivamente, il modello genererà una regola di riscrittura come indicato di seguito:

Screenshot del riquadro Modifica regola con sezioni per nome di dominio, URL, condizioni e azione.

Prerequisiti

Prima di procedere con questa procedura dettagliata, è consigliabile acquisire familiarità con i concetti di base dell'estendibilità di Gestione IIS completando le attività nell'articolo "Come creare un semplice modulo di Gestione IIS".

Progetto VS2008 per il modello di regola

Il progetto completo di Visual Studio 2008 per questo modello di regola è disponibile per il download qui.

Implementazione di un modello di regola

Per supportare la gestione remota, tutti i componenti dell'interfaccia utente di Gestione IIS vengono implementati seguendo un determinato modello di progettazione. L'implementazione di un modulo è costituita da queste parti:

  • Interfaccia utente lato client e proxy del servizio
  • Servizio lato server per la gestione della configurazione di IIS

Tutte le implementazioni specifiche dell'interfaccia utente si trovano su un lato client, che può essere un computer client remoto. Tutte le funzionalità che effettivamente apportano modifiche alla configurazione di IIS vengono implementate come servizio sul lato server, garantendo così l'accesso a tutte le API di configurazione del server. I controlli lato client interagiscono con il servizio tramite proxy del servizio.

È consigliabile implementare modelli di regola seguendo lo stesso modello, in modo che i modelli funzionino quando gli utenti creano regole tramite Gestione remota IIS. Le sezioni seguenti descrivono come implementare il servizio modello di regola e il client.

Implementazione di un'interfaccia utente lato client

Creare un modulo

In primo luogo, è necessario creare un modulo, è il punto di ingresso principale nel client per tutti gli oggetti di estendibilità. A tale scopo, eseguire queste operazioni:

  1. Creare e configurare un progetto di Visual Studio seguendo i passaggi descritti nelle attività 1 e 2 dell'articolo "Come creare un semplice modulo di Gestione IIS". Assegnare al progetto il nome "CanonicalDomainTemplateClient".
  2. Selezionare Aggiungi riferimenti dal menu Progetto e aggiungere riferimenti a Microsoft.Web.Management.dll disponibili in \Windows\System32\inetsrv:
  3. Selezionare di nuovo Aggiungi riferimento e aggiungere un riferimento a Microsoft.Web.Management.Rewrite.Client.dll disponibile in \Programmi\Assembly di riferimento\Microsoft\IIS.
  4. Selezionare di nuovo Aggiungi riferimento e aggiungere un riferimento a System.Windows.Forms.dll
  5. Selezionare l'opzione Aggiungi nuovo elemento dal menu Progetto. Nella finestra di dialogo Aggiungi nuovo elemento selezionare il modello Classe e digitare CanonicalDomainModule.cs come nome per il file.
  6. Modificare il codice in modo che abbia l'aspetto seguente:
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)); 
        }
    }
}

Questo codice inizializza una nuova istanza di una classe CanonicalDomainFeature, che implementerà la funzionalità del modello di regola. L'istanza di questa classe viene usata per registrare un'estensione di tipo RewriteTemplateFeature, ovvero un tipo da cui vengono derivati tutti i modelli di regola.

Creare una funzionalità modello di riscrittura

Quando si definisce una classe che implementa il modello di regola, sarà necessario derivare questa classe dalla classe RewriteTemplateFeature . Si tratta di una classe padre usata da tutti i modelli di regola di riscrittura URL.

  1. Selezionare l'opzione Aggiungi nuovo elemento nel menu Progetto. Selezionare il modello Classe e digitare CanonicalDomainFeature.cs come nome file.
  2. Modificare il codice in modo che abbia l'aspetto seguente:
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;
        }
    }
}

Il codice esegue le attività seguenti:

  1. Definisce il nome e il titolo per il modello di regola
  2. Passa il nome, il titolo e le icone al costruttore della classe di base in modo che vengano usati quando la finestra di dialogo "Aggiungi regole" visualizza tutti i modelli di regola registrati
  3. Definisce il metodo Run() usato per eseguire il rendering dell'interfaccia utente del modello, ovvero la finestra di dialogo modale basata su WinForm CanonicalDomainForm. Se si fa clic sul pulsante OK nella finestra di dialogo, la pagina principale dell'interfaccia utente del modulo Di riscrittura URL viene aggiornata chiamando il metodo Navigate().
  4. Infine, definisce una funzione helper GetPageType usata per ottenere la pagina principale per il modulo specificato.

Definire un proxy di servizio

Affinché un client remoto chiami un servizio, è necessario fornire un proxy di servizio. A tale scopo, aggiungere un altro file al progetto denominato CanonicalDomainModuleServiceProxy.cs e modificare il codice in esso in modo che sia simile al seguente:

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'implementazione effettiva del servizio per il metodo GenerateRule verrà aggiunta in un secondo momento.

Implementare la finestra di dialogo del modello di regola

Ora che tutto il codice di idraulica lato client di Gestione IIS viene eseguito, la parte rimanente consiste nel progettare e implementare l'interfaccia utente effettiva per il modello di regola. A tale scopo, seguire questa procedura:

  1. Selezionare l'opzione Aggiungi nuovo elemento nel menu del progetto. Nella finestra di dialogo Aggiungi nuovo elemento selezionare "Windows Form" e digitare il nome CanonicalDomainForm.cs:
    Screenshot della finestra di dialogo Aggiungi nuovo elemento con un modello di Windows Form selezionato.

  2. Usare Progettazione Windows Form di Visual Studio per disporre i controlli nel form:
    Screenshot del nuovo modulo in Progettazione Windows Form di Visual Studio.

  3. Passare alla visualizzazione codice e aggiungere il membro privato della classe che conterrà un riferimento a un proxy di servizio:

    private CanonicalDomainModuleServiceProxy _serviceProxy;
    
  4. Nella stessa classe modificare il codice del costruttore come indicato di seguito:

    public CanonicalDomainForm(CanonicalDomainModuleServiceProxy serviceProxy)
    {
       _serviceProxy = serviceProxy;
       InitializeComponent();
    }
    
  5. Nella stessa classe aggiungere la funzione helper che chiamerà il proxy del servizio per generare la regola di riscrittura con i parametri specificati da un utente:

    private void GenerateRule(string domainName)
    {
        try
        {
            _serviceProxy.GenerateRule(domainName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    
  6. Aggiungere un gestore eventi per quando si fa clic sul pulsante OK. Nel codice del gestore eventi richiamare la funzione helper GenerateRule, passando il contenuto del controllo TextBox come parametro.

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

Implementazione di un servizio per il modello di regola

Per implementare un servizio, è necessario creare un provider di moduli, ovvero un punto di ingresso per la registrazione dei moduli in Gestione IIS. A tale scopo, eseguire queste operazioni:

  1. Creare e configurare un altro progetto di Visual Studio seguendo i passaggi descritti nelle attività 1 e 2 dell'articolo "Come creare un semplice modulo di Gestione IIS". Assegnare al progetto il nome "CanonicalDomainTemplate".

  2. Selezionare Aggiungi riferimenti dal menu Progetto e aggiungere riferimenti agli assembly seguenti che si trovano in \Windows\System32\inetsrv:

    1. Microsoft.Web.Administration.dll
    2. Microsoft.Web.Management.dll
  3. Selezionare l'opzione Aggiungi nuovo elemento dal menu Progetto. Nella finestra di dialogo Aggiungi nuovo elemento selezionare il modello Classe e digitare CanonicalDomainModuleProvider.cs come nome per il file.

  4. Modificare il codice in modo che sia simile al seguente (non dimenticare di sostituire PublicKeyToken con il token di chiave pubblica dell'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;
        }
    }
}

Questo codice crea un ModuleProvider che supporta tutti i tipi di connessioni (Server, Sito e Applicazione) e registra un modulo lato client denominato CanonicalDomainModule. Registra anche il tipo di servizio del modulo CanonicalDomainModuleService usato su un lato server per generare regole di riscrittura.

Per creare un servizio per il modello di regola, seguire questa procedura:

  1. Selezionare l'opzione Aggiungi nuovo elemento nel menu Progetto. Selezionare il modello Classe e digitare CanonicalDomainModuleService.cs come nome file.
  2. Modificare il codice in modo che abbia l'aspetto seguente:
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();
        }
    }
}

Questo codice crea una regola per il reindirizzamento al dominio canonico.

Suggerimento

per ottenere rapidamente il codice per la generazione di regole di riscrittura, usare l'Editor di configurazione per IIS 7.0 e versioni successive, incluso in Administration Pack per IIS. Per altre informazioni su come generare codice per la creazione di regole di riscrittura, vedere questo articolo .

Registrazione del modello di regola con Gestione IIS

Dopo aver compilato e inserito correttamente il progetto modello di regola nella Global Assembly Cache, sarà necessario registrarlo con Gestione IIS aggiungendo le informazioni al file di administration.config.

Aprire administration.config file che si trova in \Windows\System32\inetsrv\config e aggiungere la riga seguente alla <sezione moduleProviders> . Assicurarsi di sostituire PublicKeyToken:

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

Nota

Aggiungendolo solo all'elenco di moduleProviders, si registra il modulo solo per le connessioni server. Se si vuole abilitare questo modulo per le connessioni del sito e le connessioni dell'applicazione, aggiungerlo all'elenco seguente:

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

Al termine di questi passaggi, è necessario visualizzare il modello di regola "Nome dominio canonico" nella finestra di dialogo Aggiungi regole del modulo Di riscrittura URL.