Compartir a través de


Desarrollo de una plantilla de regla para el módulo de reescritura de direcciones URL

de Ruslan Yakushev

Este tutorial le guiará a través de cómo desarrollar una plantilla de regla para el módulo de reescritura de direcciones URL. Creará una plantilla de regla que se puede usar para generar una regla de reescritura que aplique el uso de un dominio determinado para un sitio web.

Información general de la plantilla

La plantilla de regla de nombre de dominio canónico se puede usar para simplificar la creación de una regla de reescritura que se usa para aplicar el nombre de dominio canónico para un sitio web. Los usuarios pueden elegir esta plantilla en el cuadro de diálogo "Agregar reglas":

Screenshot of Add rule(s) dialog with

A continuación, los usuarios pueden proporcionar un nombre de dominio que quieran usar:

Screenshot of

Después de eso, la plantilla generará una regla de reescritura como se indica a continuación:

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

Requisitos previos

Antes de continuar con este tutorial, se recomienda familiarizarse con los conceptos básicos de extensibilidad del administrador de IIS completando las tareas del artículo "Creación de un módulo de administrador de IIS simple".

Proyecto de VS2008 para la plantilla de regla

El proyecto completo de Visual Studio 2008 para esta plantilla de regla está disponible para su descarga aquí.

Implementación de una plantilla de regla

Para admitir la administración remota, todos los componentes de la interfaz de usuario del Administrador de IIS se implementan siguiendo un determinado patrón de diseño. La implementación de un módulo consta de estas partes:

  • Interfaz de usuario del lado cliente y proxy de servicio
  • Servicio del lado servidor para administrar la configuración de IIS

Toda la implementación específica de la interfaz de usuario reside en un lado cliente, que puede ser una máquina cliente remota. Toda la funcionalidad que realmente realiza cambios en la configuración de IIS se implementa como servicio en un servidor, lo que garantiza que tiene acceso a todas las API de configuración del servidor. Los controles del lado cliente interactúan con el servicio a través del proxy de servicio.

Se recomienda implementar plantillas de regla siguiendo el mismo patrón, de modo que las plantillas funcionen cuando los usuarios creen reglas a través del administrador remoto de IIS. En las siguientes secciones se describe cómo implementar el servicio y el cliente de plantillas de reglas.

Implementación de una interfaz de usuario del lado cliente

Creación de un módulo

En primer lugar, deberá crear un módulo, es el punto de entrada principal del cliente para todos los objetos de extensibilidad. Para ello:

  1. Cree y configure un proyecto de Visual Studio siguiendo los pasos descritos en las tareas 1 y 2 del artículo "Creación de un módulo de administrador de IIS simple". Asigne al proyecto el nombre "CanonicalDomainTemplateClient".
  2. Seleccione Agregar referencias en el menú Proyecto y agregue referencias a Microsoft.Web.Management.dll ubicado en \Windows\System32\inetsrv:
  3. Seleccione Agregar referencia de nuevo y agregue la referencia a Microsoft.Web.Management.Rewrite.Client.dll ubicado en \Program Files\Reference Assemblies\Microsoft\IIS.
  4. Seleccione Agregar referencia de nuevo y agregue referencia a System.Windows.Forms.dll
  5. Seleccione la opción Agregar nuevo elemento en el menú Proyecto. En el cuadro de diálogo Agregar nuevo elemento, seleccione la plantilla Clase y escriba CanonicalDomainModule.cs como nombre del archivo.
  6. Cambie el código para que tenga el siguiente aspecto:
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)); 
        }
    }
}

Este código inicializa una nueva instancia de una clase CanonicalDomainFeature, que implementará la funcionalidad de plantilla de regla. La instancia de esta clase se usa para registrar una extensión de tipo RewriteTemplateFeature, que es un tipo del que se derivan todas las plantillas de regla.

Creación de una característica de plantilla de reescritura

Al definir una clase que implemente la plantilla de regla, deberá derivar esta clase de la clase RewriteTemplateFeature. Es una clase primaria que usa todas las plantillas de regla de reescritura de direcciones URL.

  1. Seleccione la opción Agregar nuevo elemento en el menú Proyecto. Seleccione la clase de plantilla y escriba CanonicalDomainFeature.cs como nombre de archivo.
  2. Cambie el código para que tenga el siguiente aspecto:
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;
        }
    }
}

Este código hace lo siguiente:

  1. Define el nombre y el título de la plantilla de regla
  2. Pasa el nombre, el título y los iconos al constructor de clase base para que se usen cuando el cuadro de diálogo "Agregar reglas" muestre todas las plantillas de regla registradas
  3. Define el método Run() que se usa para representar la interfaz de usuario de plantilla, que es el cuadro de diálogo modal basado en WinForm CanonicalDomainForm. Si se hace clic en el botón Aceptar en el cuadro de diálogo, la página principal de la interfaz de usuario del módulo URL Rewrite se actualiza llamando al método Navigate().
  4. Por último, define una función auxiliar GetPageType que se usa para obtener la página principal del módulo especificado.

Definición de un proxy de servicio

Para que un cliente remoto llame a un servicio, es necesario proporcionar un proxy de servicio. Para ello, agregue otro archivo al proyecto denominado CanonicalDomainModuleServiceProxy.cs y cambie el código en él para que tenga el siguiente aspecto:

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

La implementación real del servicio para el método GenerateRule se agregará más adelante.

Cuadro de diálogo Implementar la plantilla de regla

Ahora que todo el código del lado del cliente del administrador de IIS está hecho, lo que queda es diseñar e implementar la interfaz de usuario real para la plantilla de reglas. Para ello, siga estos pasos:

  1. Seleccione la opción Agregar nuevo elemento en el menú del proyecto. En el cuadro de diálogo Agregar nuevo elemento, seleccione "Formulario de Windows" y escriba el nombre CanonicalDomainForm.cs:
    Screenshot of Add New Item dialog with a Windows Form template selected.

  2. Use el diseñador de formularios de Windows de Visual Studio para organizar controles en el formulario:
    Screenshot of the new form in Visual Studio windows form designer.

  3. Cambie a la vista de código y agregue el miembro privado de la clase que contendrá una referencia a un proxy de servicio:

    private CanonicalDomainModuleServiceProxy _serviceProxy;
    
  4. En la misma clase, modifique el código del constructor como se indica a continuación:

    public CanonicalDomainForm(CanonicalDomainModuleServiceProxy serviceProxy)
    {
       _serviceProxy = serviceProxy;
       InitializeComponent();
    }
    
  5. En la misma clase, agregue la función auxiliar que llamará al proxy de servicio para generar la regla de reescritura con los parámetros especificados por un usuario:

    private void GenerateRule(string domainName)
    {
        try
        {
            _serviceProxy.GenerateRule(domainName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    
  6. Agregue un controlador de eventos para cuando se haga clic en el botón Aceptar. En el código del controlador de eventos, invoque la función auxiliar GenerateRule y pase el contenido del control TextBox como parámetro.

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

Implementación de un servicio para una plantilla de regla

Para implementar un servicio, deberá crear un proveedor de módulos, que es un punto de entrada para el registro de módulos en el administrador de IIS. Para ello:

  1. Cree y configure otro proyecto de Visual Studio siguiendo los pasos descritos en las tareas 1 y 2 del artículo "Creación de un módulo de administrador de IIS simple". Asigne al proyecto el nombre "CanonicalDomainTemplate".

  2. Seleccione Agregar referencias en el menú Proyecto y agregue referencias a los siguientes ensamblados ubicados en \Windows\System32\inetsrv:

    1. Microsoft.Web.Administration.dll
    2. Microsoft.Web.Management.dll
  3. Seleccione la opción Agregar nuevo elemento en el menú Proyecto. En el cuadro de diálogo Agregar nuevo elemento, seleccione la plantilla Clase y escriba CanonicalDomainModuleProvider.cs como nombre del archivo.

  4. Cambie el código para que tenga el siguiente aspecto (no olvide reemplazar PublicKeyToken por el token de clave pública del ensamblado de 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;
        }
    }
}

Este código crea un ModuleProvider que admite todos los tipos de conexiones (servidor, sitio y aplicación) y registra un módulo del lado cliente denominado CanonicalDomainModule. También registra el tipo del servicio de módulo CanonicalDomainModuleService que se usa en un servidor para generar reglas de reescritura.

Para crear un servicio para la plantilla de regla, siga estos pasos:

  1. Seleccione la opción Agregar nuevo elemento en el menú Proyecto. Seleccione la clase de plantilla y escriba CanonicalDomainModuleService.cs como nombre de archivo.
  2. Cambie el código para que tenga el siguiente aspecto:
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();
        }
    }
}

Este código crea una regla para el redireccionamiento al dominio canónico.

Sugerencia

para obtener rápidamente el código para generar reglas de reescritura, use el editor de configuración para IIS 7.0 y versiones posteriores, que se incluye en el Paquete de administración para IIS. Consulte este artículo para obtener más información sobre cómo generar código para la creación de reglas de reescritura.

Registro de la plantilla de regla con el administrador de IIS

Una vez que el proyecto de plantilla de regla se haya compilado y colocado correctamente en la caché global de ensamblados, deberá registrarlo con el administrador de IIS agregando su información al archivo administration.config.

Abra el archivo administration.config ubicado en \Windows\System32\inetsrv\config y agregue la siguiente línea a la sección <moduleProviders>. Asegúrese de reemplazar el PublicKeyToken:

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

Nota:

Al agregarlo solo a la lista de moduleProviders, solo se registra el módulo para las conexiones de servidor. Si desea que este módulo esté habilitado para conexiones de sitio, así como conexiones de aplicación, agréguelo a la siguiente lista:

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

Una vez realizados estos pasos, debería poder ver la plantilla de regla "Nombre de dominio canónico" en el cuadro de diálogo Añadir regla(s) del módulo de reescritura de direcciones URL.