Desenvolver um provedor de reescrita personalizado para o Módulo de Reescrita de URL

por Ruslan Yakushev

Este passo a passo orientará você sobre como desenvolver um provedor de reescrita para o Módulo de Reescrita de URL 2.0. Você criará um ReplaceProvider que substitui todas as ocorrências de um caractere específico no URL por outro caractere. Esse tipo de lógica é realmente difícil e, às vezes, impossível de expressar em termos de expressões regulares, daí a necessidade de criar um provedor de reescrita personalizado.

Criar um projeto do Visual Studio

Para criar um projeto do Visual Studio para provedor de reescrita, siga estas etapas:

  1. Abra o Microsoft Visual Studio 2008 ou a Edição Expressa do Microsoft Visual C# 2008.

  2. No menu Arquivo, selecione “Novo Projeto...”.

  3. Na caixa de diálogo “Novo Projeto”, selecione o modelo de projeto “Biblioteca de Classes” e nomeie o projeto ReplaceProvider.
    Screenshot of the New Project dialog with Class Library project template option being highlighted.

  4. Remova o arquivo Class1.cs adicionado por padrão (já que você não usará esse arquivo) usando a opção Excluir do menu de contexto no Gerenciador de Soluções;

  5. Selecione “Adicionar Referências...” no menu Projeto e adicione referências ao Microsoft.Web.Iis.Rewrite.dll localizado em %ProgramFiles%\Reference Assemblies\Microsoft\IIS.

  6. Os provedores de reescrita devem ser colocados no GAC (Cache de Assembly Global) do .NET para ficarem visíveis para o Módulo de Reescrita de URL. Isso exige que a DLL do assembly do provedor seja fortemente nomeada (assinada). Para assinar o assembly, selecione a opção “Propriedades do ReplaceProvider...” no menu “Projeto”.

  7. Na caixa de seleção “Assinar o assembly”, marque o guia Assinatura.

  8. Na caixa de combinação, selecione a opção <Novo...> para criar uma nova chave. Na caixa de diálogo “Criar Chave de Nome Forte”, digite DemoKey.snk como o nome da chave e desmarque o arquivo Proteger minha chave com uma caixa de seleção de senha. Clique em OK.
    Screenshot of the Create Strong Name Key dialog, which contains the Key file name, Enter password, and Confirm password fields.
    O guia Assinatura deve ser exibido como abaixo:
    Screenshot of the signing tab showing the entered key file name in the Choose a strong name key file field.

  9. Selecione o guia “Eventos de Build” e adicione a seguinte linha de comando “Evento pós-build”:

    CHAMAR %VS90COMNTOOLS%\vsvars32.bat> NULL
    gacutil.exe /if "$(TargetPath)"

    Observação: caso use o Visual Studio 2010, substitua %VS90COMNTOOLS% por %VS100COMNTOOLS%.

Implementar as interfaces do provedor

Para implementar um provedor de reescrita, siga as etapas abaixo:

  1. No menu Projeto, selecione “Adicionar Classe...” e nomeie a classe como ReplaceProvider. Isso adicionará um novo arquivo ReplaceProvider.cs ao projeto.
  2. Altere o código para que ele se pareça com o seguinte:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Web.Iis.Rewrite;

public class ReplaceProvider: IRewriteProvider, IProviderDescriptor
{
    char oldChar, newChar;

    #region IRewriteProvider Members

    public void Initialize(IDictionary<string, string> settings, IRewriteContext rewriteContext)
    {
        string oldCharString, newCharString;

        if (!settings.TryGetValue("OldChar", out oldCharString) || string.IsNullOrEmpty(oldCharString))
            throw new ArgumentException("OldChar provider setting is required and cannot be empty");

        if (!settings.TryGetValue("NewChar", out newCharString) || string.IsNullOrEmpty(newCharString))
            throw new ArgumentException("NewChar provider setting is required and cannot be empty");

        if (!string.IsNullOrEmpty(oldCharString))
            oldChar = oldCharString.Trim()[0];
        else
            throw new ArgumentException("OldChar parameter cannot be empty");

        if (!string.IsNullOrEmpty(newCharString))
            newChar = newCharString.Trim()[0];
        else
            throw new ArgumentException("NewChar parameter cannot be empty");
    }

    public string Rewrite(string value)
    {
        return value.Replace(oldChar, newChar);
    }

    #endregion

    #region IProviderDescriptor Members

    public IEnumerable<SettingDescriptor> GetSettings()
    {
        yield return new SettingDescriptor("OldChar", "Old Character");
        yield return new SettingDescriptor("NewChar", "New Character");
    }

    #endregion
}

O código acima implementa duas interfaces:

IRewriteProvider – essa é a interface principal que precisa ser implementada. Ele é usado para inicializar o provedor passando para ele suas configurações. Além disso, ele é usado para executar o provedor.

IProviderDescriptor – essa é uma interface opcional e pode ser usada para informar o Gerenciador do IIS sobre os nomes e descrições das configurações usadas pelo provedor.

Registrar e configurar o provedor

Uma vez que o provedor tenha sido criado e colocado com êxito no GAC, ele precisará ser registrado com o Módulo de Reescrita de URL do IIS. Para registrar o provedor:

  1. Abra o Gerenciador do IIS e selecione o recurso de Reescrita de URL
  2. Clique em “Exibir Provedores...” ação:
    Screenshot of the I I S Manager with a focus on the View Providers option in the Manage Providers section of the Actions pane.
  3. Na página Provedores, selecione Adicionar Provedor... ação e, em seguida, insira o nome do provedor como ReplaceProvider e escolha o tipo de provedor no Tipo Gerenciado: lista suspensa.
    Screenshot of the View Providers option in the Actions pane.
  4. Clique em OK para salvar as alterações.
  5. Agora selecione “Adicionar Configuração do Provedor...” ação. Observe que a lista suspensa “Name:” mostra as configurações que foram retornadas pelo método IProviderDescriptor.GetSettings(). Selecione a configuração de Caractere Antigo e insira "_" como um valor.
    Screenshot of the Edit Provider Setting screen within the Rewrite Providers section of the I I S Manager screen.
  6. Selecione OK para salvar a configuração
  7. Repita as etapas 5 e 6, mas agora escolha “Novo Caractere” e especifique “-” como um valor. Isso significa que o provedor será usado para substituir todas as ocorrências de caractere “_” por caractere “-” na cadeia de caracteres de entrada.

Isso conclui o registro e a configuração de um provedor de regravação. Como resultado, o arquivo web.config para o site padrão conterá o seguinte código XML dentro da seção <rewrite>:

<rewrite>
    <providers>
        <provider name="ReplaceProvider" type="ReplaceProvider, ReplaceProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=157df8edcf6cf889">
            <settings>
                <add key="OldChar" value="_" />
                <add key="NewChar" value="-" />
            </settings>
        </provider>
    </providers>
</rewrite>

Usar o provedor de reescrita

Agora que o provedor de reescrita foi registrado, ele pode ser usado nas regras de entrada e saída. Para testar o provedor, você criará uma regra que redireciona todas as solicitações de URLs que têm o símbolo “_” para o URL em que esse símbolo é substituído por “-”. Por exemplo, uma solicitação para um URL como essa http://localhost/some_blog_post/ será redirecionada para http://localhost/some-blog-post/.

Para criar uma regra que usa esse provedor de reescrita, adicione o seguinte código do XML dentro do elemento <rewrite> no arquivo web.config:

<rules>
    <rule name="ReplaceProviderTest" stopProcessing="true">
        <match url="_" />
        <action type="Redirect" url="{ReplaceProvider:{URL}}" />
    </rule>
</rules>

Abra um navegador da Web e faça uma solicitação para http://localhost/some_blog_post/. observar que o navegador foi redirecionado para http://localhost/some-blog-post/ devido à regra adicionada. O servidor Web retornará o erro HTTP 404 ao URL redirecionado porque não há nenhum arquivo ou diretório no servidor, mas isso não é relevante para os fins deste passo a passo. A parte importante é que o servidor Web emitiu uma resposta de redirecionamento com base na regra que usou o provedor de reescrita personalizado.