Reescrita de URL para ASP.NET Web Forms
Quando você usa o módulo de Reescrita de URL do IIS com aplicativos do ASP.NET, é importante garantir o comportamento correto do aplicativo Web com URLs reescritas. Este artigo explica cenários nos quais a reescrita de URL pode afetar os aplicativos Web do ASP.NET e as soluções para possíveis problemas.
Sumário
- Configuração da URL de Postback para o Elemento de Formulário
- Reescrita de URLs para o Controle UpdatePanel do AJAX
- Uso do Operador "~" nos Controles de Servidor Web
- Reescrita de URLs e Controles de Navegação no Site
- Impedir Reescrita de Solicitações para recursos do ASP.NET
Configuração da URL de Postback para o Elemento de Formulário
O ASP.NET Web Forms usam postbacks extensivamente, e isso complica um pouco a reescrita de URL para páginas do ASP.NET. Se a página contiver um ou mais controles de servidor Web, quando o ASP.NET renderizar a página, ele definirá o atributo action do elemento de formulário HTML para apontar novamente para a página na qual está o elemento de formulário, ou seja, ele apontará para si mesmo. Se a reescrita de URL for usada para essa página, o atributo action apontará para a URL reescrita, e não para a URL que foi solicitada no navegador. Isso faz com que o navegador exiba a URL reescrita na caixa de endereço, sempre que ocorrer um postback.
Para impedir que o atributo action aponte para a URL errada, você pode definir a propriedade Action da instância HtmlForm na página como a URL de postback solicitada pelo navegador. Você pode obter essa URL usando a propriedade HttpRequest.RawUrl. O exemplo a seguir mostra como você pode modificar a página do ASP.NET para definir a URL de ação.
protected void Page_Load(object sender, EventArgs e)
{
form1.Action = Request.RawUrl;
}
Observação
A propriedade HtmlForm.Action está disponível a partir do .NET Framework versão 3.5 SP1.
Se você estiver usando as páginas mestras do ASP.NET, poderá adicionar o código ao método Page_Load da página mestra para definir a URL de ação de postback para todas as páginas que usam essa página mestra.
Reescrita de URLs para o Controle UpdatePanel do AJAX
Quando você usa o módulo de Reescrita de URL para reescrever a URL de uma página que contém um ou mais controles UpdatePanel, o controle usará a URL reescrita para todas as ações executadas por esse controle UpdatePanel. Isso pode fazer com que os controles no controle UpdatePanel não funcionem corretamente, especialmente nos casos em que a reescrita de URL altera a hierarquia de diretório da URL solicitada. Por exemplo, se você usar o módulo de Reescrita de URL para reescrever /Products/Hardware em /Products.aspx, o controle UpdatePanel usará a URL /Products/Hardware/Products.aspx para todas as ações dentro do controle UpdatePanel. Isso resulta em um erro de script.
Para evitar que isso aconteça, defina a propriedade Action da instância HtmlForm da página, conforme descrito em Configuração da URL de Postback para o Elemento de Formulário na seção anterior.
Uso do Operador ~ nos Controles de Servidor Web
Você pode usar o operador ~ nos controles de servidor Web do ASP.NET para referenciar a raiz do diretório do aplicativo, quando precisar definir um caminho. No entanto, se a reescrita de URL alterar a hierarquia de diretórios da URL solicitada, isso poderá fazer com que os links especificados com o operador ~ sejam resolvidos de maneira incorreta. Por exemplo, imagine que a página Default.aspx na raiz de um aplicativo Web chamado app1 contém o seguinte controle Image:
<asp:Image runat="server" ImageUrl="~/Images/MyImage.gif" />
Se a reescrita de URL alterar a URL de http://localhost/app1/folder/file
para http://localhost/app1/default.aspx
, os links especificados com o operador ~ serão resolvidos em relação ao caminho da URL reescrita, que seria relativo à pasta /app1. O exemplo a seguir mostra a marcação HTML resultante para o elemento img:
<img src="Images/MyImage.gif" ... >
Como o navegador solicitou http://localhost/app1/folder/file
, ele tentará obter a imagem do http://localhost/app1/folder/Images/MyImage.gif
. Isso resulta em um erro 404 (Arquivo Não Encontrado).
O módulo de Reescrita de URL para IIS inclui uma atualização para ASP.NET que corrige esse comportamento. A atualização fará com que o operador ~ nos controles de servidor Web seja resolvido em relação à URL solicitada originalmente. No exemplo anterior, a marcação HTML na resposta conterá o caminho de URL correto para o elemento img, conforme mostrado na marcação a seguir:
<img src="../Images/MyImage.gif" ... >
A atualização para ASP.NET se aplica somente ao .NET Framework 3.5 SP1 e versões posteriores. Para obter a atualização, atualize o .NET Framework para a versão 3.5 SP1 e, em seguida, execute o instalador do módulo de Reescrita de URL do IIS, que instalará a atualização do ASP.NET.
Reescrita de URLs e Controles de Navegação no Site
Um mapa do site do ASP.NET pode ser usado para descrever a estrutura de um site para que a API de navegação no site e os controles de navegação o site possam expor uma estrutura de site lógica (em vez de física). Quando você usa o módulo de Reescrita de URL com um aplicativo do ASP.NET que usa a navegação no site, normalmente você deseja que os controles de navegação operem em termos de estrutura lógica do site que usa URLs públicas ou virtuais.
Por exemplo, você pode definir um mapa do site conforme mostrado no exemplo a seguir:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
<siteMapNode url="~/Products/" title="Products" description="Products Home Page">
<siteMapNode url="~/Products/Hardware/" title="Hardware" description="Hardware Products" />
<siteMapNode url="~/Products/Software/" title="Software" description="Software Products" />
</siteMapNode>
</siteMap>
Em seguida, você pode definir as regras de reescrita que executam as seguintes reescritas:
- /Products/ para /Products.aspx
- /Products/Hardware para /Products.aspx?category=Hardware
- /Products/Software para /Products.aspx?category=Software
Definir um mapa do site usando essas URLs virtuais pode fazer com que a classe SystemWeb.SiteMap não funcione corretamente. Quando você tenta acessar a propriedade SiteMap.CurrentNode em uma página do ASP.NET, a propriedade pode conter null. Isso pode fazer com que controles de navegação no site, como SiteMapPath e Menu, funcionem de maneira incorreta.
O módulo de Reescrita de URL para IIS inclui uma atualização para ASP.NET que corrige os controles de navegação para que eles possam trabalhar com URLs virtuais reescritas. Com essa atualização, a propriedade SiteMap.CurrentNode fará referência ao SiteMapNode que corresponde à URL virtual solicitada no momento.
A atualização para ASP.NET se aplica somente ao .NET Framework 3.5 SP1 e versões posteriores. Para obter a atualização, atualize o .NET Framework para a versão 3.5 SP1 e, em seguida, execute o instalador do módulo de Reescrita de URL do IIS, que instalará a atualização do ASP.NET.
Impedir Reescrita de Solicitações para recursos do ASP.NET Web
Muito frequentemente os aplicativos Web do ASP.NET fazem solicitações ao arquivo WebResources.axd para recuperar recursos de assembly e fornecê-los ao navegador da Web. Esse arquivo não existe no servidor porque o ASP.NET gera o conteúdo dinamicamente quando o WebResources.axd é solicitado. Portanto, se você tiver uma regra de reescrita de URL que faça reescrita ou redirecionamento somente se a URL solicitada não corresponder a um arquivo ou pasta no sistema de arquivos de um servidor Web, essa regra poderá regravar acidentalmente as solicitações feitas no WebResources.axd e, assim, interromper o aplicativo.
Esse problema pode ser evitado facilmente se você adicionar uma condição extra à regra de reescrita:
<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
<match url="^([^/]+)/?$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<!-- The following condition prevents rule from rewriting requests to .axd files -->
<add input="{URL}" negate="true" pattern="\.axd$" />
</conditions>
<action type="Rewrite" url="article.aspx?p={R:1}" />
</rule>