URLs em páginas mestras (VB)

por Scott Mitchell

Baixar PDF

Aborda como as URLs na página master podem ser interrompidas devido ao arquivo de página master estar em um diretório relativo diferente da página de conteúdo. Examina a rebasing de URLs por meio de ~ na sintaxe declarativa e usando ResolveUrl e ResolveClientUrl programaticamente. (Veja também

Introdução

Em todos os exemplos que vimos até agora, as master e as páginas de conteúdo foram localizadas na mesma pasta (a pasta raiz do site). Mas não há razão para que as páginas de master e conteúdo estejam na mesma pasta. Você certamente pode criar páginas de conteúdo em subpastas. Da mesma forma, você pode criar uma ~/MasterPages/ pasta na qual coloca as páginas master do site.

Um possível problema com a colocação de master e páginas de conteúdo em pastas diferentes envolve URLs quebradas. Se a página master contiver URLs relativas em hiperlinks, imagens ou outros elementos, o link será inválido para páginas de conteúdo que residem em uma pasta diferente. Neste tutorial, examinamos a origem desse problema, bem como soluções alternativas.

O problema com URLs relativas

Uma URL em uma página da Web será considerada uma URL relativa se o local do recurso para o qual ele aponta for relativo ao local da página da Web na estrutura de pastas do site. Qualquer URL que não comece com uma barra inicial (/) ou um protocolo (como http://) é relativa porque é resolvida pelo navegador com base no local da página da Web que contém a URL.

Por exemplo, nosso site tem uma ~/Images/ pasta com um único arquivo de imagem, PoweredByASPNET.gif. O arquivo Site.master de página master tem um <img> elemento na footerContent região com a seguinte marcação:

<div id="footerContent">
 <img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>

O src valor do atributo no <img> elemento é uma URL relativa porque não começa com / ou http://. Em resumo, o valor do src atributo instrui o navegador a procurar na Images subpasta um arquivo chamado PoweredByASPNET.gif.

Ao visitar uma página de conteúdo, a marcação acima é enviada diretamente para o navegador. Reserve um momento para visitar About.aspx e exibir a fonte HTML enviada ao navegador. Você descobrirá que exatamente a mesma marcação na página master foi enviada ao navegador.

<div id="footerContent">
 <img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>

Se a página de conteúdo estiver na pasta raiz (como é About.aspx), tudo funcionará conforme o esperado porque há uma Images subpasta em relação à pasta raiz. No entanto, as coisas serão interrompidas se a página de conteúdo estiver em uma pasta diferente da página master. Para ilustrar isso, crie uma subpasta chamada Admin. Em seguida, adicione uma página de conteúdo chamada Default.aspx à Admin pasta , certificando-se de associar a nova página à Site.master página master.

Observação

No tutorial Especificando o título, metamaras e outros cabeçalhos HTML na Página Mestra , criamos uma classe de página base personalizada chamada BasePage que define automaticamente o título da página de conteúdo (se não tiver sido explicitamente atribuído). Não se esqueça de ter a classe code-behind da página recém-criada derivada de BasePage para que ela possa utilizar essa funcionalidade.

Depois de criar essa página de conteúdo, sua Gerenciador de Soluções deverá ser semelhante à Figura 1.

Uma nova pasta e uma página de ASP.NET foram adicionadas ao projeto

Figura 01: Uma nova pasta e uma página de ASP.NET foram adicionadas ao projeto

Em seguida, atualize o Web.sitemap arquivo para incluir uma nova <siteMapNode> entrada para esta lição. O XML a seguir mostra a marcação completa Web.sitemap , que agora inclui a adição de um terceiro <siteMapNode> elemento.

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
 <siteMapNode url="~/Default.aspx" title="Home">
 <siteMapNode url="~/About.aspx" title="About the Author" />
 <siteMapNode url="~/MultipleContentPlaceHolders.aspx" title="Using Multiple ContentPlaceHolder Controls" />
 <siteMapNode url="~/Admin/Default.aspx" title="Rebasing URLs" />
 </siteMapNode>
</siteMap>

A página recém-criada Default.aspx deve ter quatro controles de conteúdo correspondentes aos quatro ContentPlaceHolders no Site.master. Adicione algum texto ao Controle de conteúdo referenciando o MainContent ContentPlaceHolder e visite a página por meio de um navegador. Como mostra a Figura 2, o navegador não pode localizar o arquivo de PoweredByASPNET.gif imagem. O que está acontecendo?

A ~/Admin/Default.aspx página de conteúdo é enviada o mesmo HTML para a footerContent região como foi a About.aspx página:

<div id="footerContent">
 <img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>

Como o <img> atributo do src elemento é uma URL relativa, o navegador tenta procurar uma Images pasta em relação ao local da pasta da página da Web. Em outras palavras, o navegador está procurando o arquivo Admin/Images/PoweredByASPNET.gifde imagem .

O arquivo de imagem PoweredByASPNET.gif não pode ser encontrado

Figura 02: O PoweredByASPNET.gif arquivo de imagem não pode ser encontrado (clique para exibir a imagem em tamanho real)

Substituindo URLs relativas por URLs absolutas

O oposto de uma URL relativa é uma URL absoluta, que é aquela que começa com uma barra (/) ou um protocolo como http://. Como uma URL absoluta especifica o local de um recurso de um ponto fixo conhecido, a mesma URL absoluta é válida em qualquer página da Web, independentemente do local da página da Web na estrutura de pastas do site.

Para corrigir a imagem quebrada mostrada na Figura 2, precisamos atualizar o <img> atributo do src elemento para que ele use uma URL absoluta em vez de uma relativa. Para determinar a URL absoluta correta, visite uma das páginas da Web em seu site e examine a Barra de endereços. Como mostra a barra de endereços na Figura 2, o caminho totalmente qualificado para o aplicativo Web é http://localhost:3908/ASPNET_MasterPages_Tutorial_04_VB/. Portanto, poderíamos atualizar o <img> atributo do src elemento para uma das duas URLs absolutas a seguir:

  • /ASPNET_MasterPages_Tutorial_04_VB/Images/PoweredByASPNET.gif
  • http://localhost:3908/ASPNET_MasterPages_Tutorial_04_VB/Images/PoweredByASPNET.gif

Reserve um momento para atualizar o <img> atributo do src elemento para uma URL absoluta usando um dos formulários mostrados acima e, em seguida, visite a ~/Admin/Default.aspx página por meio de um navegador. Desta vez, o navegador localizará e exibirá corretamente o PoweredByASPNET.gif arquivo de imagem (consulte a Figura 3).

A imagem PoweredByASPNET.gif agora é exibida

Figura 03: A PoweredByASPNET.gif imagem agora é exibida (clique para exibir a imagem em tamanho real)

Embora a codificação rígida na URL absoluta funcione, ela associa firmemente seu HTML ao local do servidor e da pasta do site, o que pode mudar. O uso de uma URL absoluta do formulário http://localhost:3908/... é frágil porque o número da porta anterior ao localhost é selecionado automaticamente sempre que o servidor Web de desenvolvimento de ASP.NET interno do Visual Studio é iniciado. Da mesma forma, a http://localhost parte só é válida ao testar localmente. Depois que o código for implantado em um servidor de produção, a base de URL será alterada para outra coisa, como http://www.yourserver.com. A URL absoluta no formulário /ASPNET_MasterPages_Tutorial_04_VB/... também sofre da mesma fragilidade porque, muitas vezes, esse caminho de aplicativo difere entre servidores de desenvolvimento e produção.

A boa notícia é que ASP.NET oferece um método para gerar uma URL relativa válida em runtime.

Usando~eResolveClientUrl

Em vez de codificar uma URL absoluta, ASP.NET permite que os desenvolvedores de página usem o til (~) para indicar a raiz do aplicativo Web. Por exemplo, anteriormente neste tutorial, usei a notação ~/Admin/Default.aspx no texto para fazer referência à Default.aspx página na Admin pasta . O ~ indica que a Admin pasta é uma subpasta da raiz do aplicativo Web.

O Control método da classe usa uma URL e a modifica para uma URL relativa apropriada para a página da ResolveClientUrl Web na qual o controle reside. Por exemplo, chamar ResolveClientUrl("~/Images/PoweredByASPNET.gif") de About.aspx retorna Images/PoweredByASPNET.gif. Chamá-lo de ~/Admin/Default.aspx, no entanto, retorna ../Images/PoweredByASPNET.gif.

Observação

Como todos os controles de servidor ASP.NET derivam da Control classe , todos os controles de servidor têm acesso ao ResolveClientUrl método . Até mesmo a Page classe deriva da classe , o Control que significa que você pode usar esse método diretamente das classes code-behind de suas ASP.NET páginas.

Usando~na Marcação Declarativa

Vários ASP.NET controles da Web incluem propriedades relacionadas à URL: o controle HyperLink tem uma NavigateUrl propriedade; o controle Image tem uma ImageUrl propriedade e assim por diante. Quando renderizados, esses controles passam seus valores de propriedade relacionados à URL para ResolveClientUrl. Consequentemente, se essas propriedades contiverem um ~ para indicar a raiz do aplicativo Web, a URL será modificada para uma URL relativa válida.

Tenha em mente que apenas ASP.NET controles de servidor transformam o ~ em suas propriedades relacionadas à URL. Se um ~ aparecer na marcação HTML estática, como <img src="~/Images/PoweredByASPNET.gif" />, o mecanismo de ASP.NET enviará o ~ para o navegador junto com o restante do conteúdo HTML. O navegador pressupõe que o ~ faz parte da URL. Por exemplo, se o navegador receber a marcação <img src="~/Images/PoweredByASPNET.gif" /> , ele assumirá que há uma subpasta chamada ~ com uma subpasta Images que contém o arquivo PoweredByASPNET.gifde imagem .

Para corrigir a marcação de imagem no Site.master, substitua o elemento existente <img> por um controle web ASP.NET Image. Defina o controle web de ID imagem como PoweredByImage, sua ImageUrl propriedade como ~/Images/PoweredByASPNET.gife sua AlternateText propriedade como "Alimentado por ASP.NET!"

<div id="footerContent">
 <asp:Image ID="PoweredByImage" runat="server" ImageUrl="~/Images/PoweredByASPNET.gif" 
    AlternateText="Powered by ASP.NET!" />
</div>

Depois de fazer essa alteração na página master, reveja a ~/Admin/Default.aspx página novamente. Desta vez, o PoweredByASPNET.gif arquivo de imagem aparece na página (consulte a Figura 3). Quando o controle web de imagem é renderizado, ele usa o ResolveClientUrl método para resolve seu ImageUrl valor de propriedade. ImageUrl No ~/Admin/Default.aspx é convertido em uma URL relativa apropriada, como mostra o seguinte snippet de origem HTML:

<div id="footerContent">
 <img id="ctl00_PoweredByImage" src="../Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>

Observação

Além de ser usado em propriedades de controle da Web baseadas em URL, o ~ também pode ser usado ao chamar os Response.Redirect métodos e Server.MapPath , entre outros. Além disso, o ResolveClientUrl método pode ser invocado diretamente de um ASP.NET ou master marcação declarativa da página.

Corrigir as URLs relativas restantes da página mestra

Além do <img> elemento no footerContent que acabamos de corrigir, a página master contém mais uma URL relativa que requer nossa atenção. A topContent região inclui o link "Tutoriais de Páginas Mestras", que aponta para Default.aspx.

<div id="topContent">
 <a href="Default.aspx">Master Pages Tutorials</a>
</div>

Como essa URL é relativa, ela enviará o usuário para a Default.aspx página na pasta da página de conteúdo que ele está visitando. Para que esse link sempre aponte para na pasta raiz, precisamos substituir o <a> elemento por um controle da Web HyperLink para Default.aspx que possamos usar a ~ notação.

Remova a marcação do <a> elemento e adicione um controle HyperLink em seu lugar. Defina o HyperLink como IDlnkHome, sua NavigateUrl propriedade como ~/Default.aspxe sua Text propriedade como "Tutoriais de Páginas Mestras".

<div id="topContent">
 <asp:HyperLink ID="lnkHome" runat="server" NavigateUrl="~/Default.aspx"
    Text="Master Pages Tutorials" />
</div>

É isso! Neste ponto, todas as URLs em nossa página master são adequadamente baseadas quando renderizadas por uma página de conteúdo, independentemente de quais pastas a página master e a página de conteúdo estão localizadas.

Resolução automática de URL na<head>seção

No tutorial Criando um layout de Site-Wide usando páginas mestras , adicionamos um <link> ao Styles.css arquivo na <head> região:

<head runat="server">
 <title>Untitled Page</title>
 <asp:ContentPlaceHolder id="head" runat="server">
 </asp:ContentPlaceHolder>
 <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>

Embora o <link> atributo do href elemento seja relativo, ele é convertido automaticamente em um caminho apropriado em runtime. Como discutimos no tutorial Especificando o título, metamarques e outros cabeçalhos HTML na Página Mestra , a <head> região é, na verdade, um controle do lado do servidor, que permite modificar o conteúdo de seus controles internos quando ele é renderizado.

Para verificar isso, reveja a ~/Admin/Default.aspx página e exiba a origem HTML enviada ao navegador. Como ilustra o snippet abaixo, o <link> atributo do href elemento foi modificado automaticamente para uma URL relativa apropriada, ../Styles.css.

<head>
 <title>
 Default
 </title>
 <link href="../Styles.css" rel="stylesheet" type="text/css" />
</head>

Resumo

As páginas mestras geralmente incluem links, imagens e outros recursos externos que devem ser especificados por meio de uma URL. Como as páginas de master e conteúdo podem não existir na mesma pasta, é importante abster-se de usar URLs relativas. Embora seja possível usar URLs absolutas codificadas, fazer isso associa firmemente a URL absoluta ao aplicativo Web. Se a URL absoluta mudar - como geralmente faz ao mover ou implantar um aplicativo Web - você precisará lembrar de voltar e atualizar as URLs absolutas.

A abordagem ideal é usar o bloco (~) para indicar a raiz do aplicativo. ASP.NET controles Web que contêm propriedades relacionadas à URL mapeiam o ~ para a raiz do aplicativo em runtime. Internamente, os controles da Web usam o Control método da ResolveClientUrl classe para gerar uma URL relativa válida. Esse método é público e está disponível em todos os controles de servidor (incluindo a Page classe), para que você possa usá-lo programaticamente em suas classes code-behind, se necessário.

Programação feliz!

Leitura Adicional

Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:

Sobre o autor

Scott Mitchell, autor de vários livros do ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Microsoft Web desde 1998. Scott trabalha como consultor independente, treinador e escritor. Seu último livro é Sams Teach Yourself ASP.NET 3.5 em 24 Horas. Scott pode ser contatado em mitchell@4GuysFromRolla.com ou através de seu blog em http://ScottOnWriting.NET.

Agradecimentos Especiais

Interessado em revisar meus próximos artigos do MSDN? Nesse caso, solte-me uma linha em mitchell@4GuysFromRolla.com.