URLs em páginas mestras (VB)
por Scott Mitchell
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.
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.gif
de imagem .
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).
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.gif
de 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.gif
e 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 ID
lnkHome
, sua NavigateUrl
propriedade como ~/Default.aspx
e 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.