URL-адреса на эталонных страницах (VB)
Сведения о том, как МОГУТ прерываться URL-адреса на странице master из-за того, что файл master страницы в относительном каталоге, отличном от каталога страницы содержимого. Выполняется перебазирование URL-адресов с помощью ~ в декларативном синтаксисе и использование ResolveUrl и ResolveClientUrl программным способом. (Также посмотрите на
Введение
Во всех примерах, которые мы видели до сих пор, страницы master и содержимого находятся в одной папке (корневой папке веб-сайта). Но нет причин, по которой master и страницы содержимого должны находиться в одной папке. Вы можете создавать страницы содержимого во вложенных папках. Аналогичным образом можно создать папку, в которую ~/MasterPages/
вы размещаете страницы master сайта.
Одна из потенциальных проблем с размещением master и страниц содержимого в разных папках связана с неисправными URL-адресами. Если страница master содержит относительные URL-адреса в гиперссылках, изображениях или других элементах, ссылка будет недопустимой для страниц контента, находящихся в другой папке. В этом руководстве мы рассмотрим источник этой проблемы, а также способы ее решения.
Проблема с относительными URL-адресами
URL-адрес веб-страницы считается относительным, если расположение ресурса, на который он указывает, соответствует расположению веб-страницы в структуре папок веб-сайта. Любой URL-адрес, который не начинается с косой черты (/
) или протокола (например, ), является относительным, так как http://
он разрешается браузером в зависимости от расположения веб-страницы, содержащей URL-адрес.
Например, на нашем веб-сайте есть ~/Images/
папка с одним файлом изображения , PoweredByASPNET.gif
. Файл Site.master
master подкачки содержит <img>
элемент в регионе footerContent
со следующей разметкой:
<div id="footerContent">
<img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>
Значение src
атрибута в элементе <img>
является относительным URL-адресом, так как оно не начинается с /
или http://
. Короче говоря, значение атрибута src
указывает браузеру, что нужно искать во Images
вложенной папке файл с именем PoweredByASPNET.gif
.
При посещении страницы содержимого приведенная выше разметка отправляется непосредственно в браузер. About.aspx
Посетите и просмотрите источник HTML, отправленный в браузер. Вы увидите, что точно такая же разметка на странице master была отправлена в браузер.
<div id="footerContent">
<img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>
Если страница содержимого находится в корневой папке (как есть About.aspx
), все работает должным образом, так как имеется вложенная Images
папка относительно корневой папки. Однако все сломается, если страница содержимого находится в папке, отличной от папки master страницы. Чтобы проиллюстрировать это, создайте вложенную папку с именем Admin
. Затем добавьте в папку страницу содержимого Admin
с именем Default.aspx
, привязав новую страницу к Site.master
master странице.
Примечание
В учебнике Указание заголовка, метатегов и других заголовков HTML в главной странице мы создали пользовательский класс базовой страницы с именем BasePage
, который автоматически задает заголовок страницы содержимого (если он не был назначен явным образом). Не забудьте создать класс кода программной части страницы, производный от BasePage
, чтобы он мог использовать эту функцию.
После создания этой страницы содержимого Обозреватель решений должны выглядеть примерно так, как на рисунке 1.
Рис. 01. В проект добавлены новая папка и страница ASP.NET
Затем обновите Web.sitemap
файл, включив в него новую <siteMapNode>
запись для этого занятия. В следующем XML-коде показана полная Web.sitemap
разметка, которая теперь включает в себя добавление третьего <siteMapNode>
элемента.
<?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>
Только что созданная Default.aspx
страница должна иметь четыре элемента управления Контентом, соответствующие четырем ContentPlaceHolders в Site.master
. Добавьте текст в элемент управления Контент, ссылающийся на MainContent
ContentPlaceHolder, а затем перейдите на страницу через браузер. Как показано на рисунке 2, браузеру не удается найти PoweredByASPNET.gif
файл изображения. В чем причина?
Страница ~/Admin/Default.aspx
содержимого отправляется в тот же HTML-код для региона, footerContent
что и About.aspx
страница:
<div id="footerContent">
<img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>
<img>
Так как атрибут элемента src
является относительным URL-адресом, браузер пытается найти Images
папку относительно расположения папки веб-страницы. Другими словами, браузер ищет файл Admin/Images/PoweredByASPNET.gif
изображения .
Рис. 02. Не PoweredByASPNET.gif
удается найти файл изображения (щелкните для просмотра полноразмерного изображения)
Замена относительных URL-адресов абсолютными URL-адресами
Напротив относительного URL-адреса является абсолютный URL-адрес, который начинается с косой черты (/
) или протокола, http://
например . Поскольку абсолютный URL-адрес указывает расположение ресурса из известной фиксированной точки, один и тот же абсолютный URL-адрес действителен на любой веб-странице, независимо от расположения веб-страницы в структуре папок веб-сайта.
Чтобы исправить неработающее изображение, показанное на рис. 2, необходимо обновить <img>
атрибут элемента src
, чтобы он использовал абсолютный URL-адрес вместо относительного. Чтобы определить правильный абсолютный URL-адрес, посетите одну из веб-страниц на веб-сайте и просмотрите адресную строку. Как показано в адресной строке на рис. 2, полный путь к веб-приложению — http://localhost:3908/ASPNET_MasterPages_Tutorial_04_VB/
. Таким образом, можно обновить <img>
атрибут элемента src
на один из следующих двух абсолютных URL-адресов:
/ASPNET_MasterPages_Tutorial_04_VB/Images/PoweredByASPNET.gif
http://localhost:3908/ASPNET_MasterPages_Tutorial_04_VB/Images/PoweredByASPNET.gif
Найдите минутку, чтобы обновить <img>
атрибут элемента src
до абсолютного URL-адреса с помощью одной из приведенных выше форм, а затем посетите страницу ~/Admin/Default.aspx
в браузере. На этот раз браузер правильно найдет и отобразит PoweredByASPNET.gif
файл изображения (см. рис. 3).
Рис. 03. Изображение PoweredByASPNET.gif
теперь отображается (щелкните для просмотра полноразмерного изображения)
Хотя жесткое кодирование в абсолютном URL-адресе работает, он тесно связан с HTML-кодом с расположением сервера и папки веб-сайта, что может измениться. Использование абсолютного URL-адреса формы http://localhost:3908/...
является хрупким, так как номер порта, предшествующий localhost, выбирается автоматически при каждом запуске встроенного веб-сервера разработки ASP.NET Visual Studio. Аналогичным образом, часть http://localhost
действительна только при локальном тестировании. После развертывания кода на рабочем сервере база URL-адреса изменится на что-то другое, например http://www.yourserver.com
. Абсолютный URL-адрес в форме /ASPNET_MasterPages_Tutorial_04_VB/...
также страдает от той же хрупкости, так как часто этот путь приложения отличается между серверами разработки и рабочей средой.
Хорошей новостью является то, что ASP.NET предлагает метод для создания допустимого относительного URL-адреса во время выполнения.
Использование~
иResolveClientUrl
Вместо жесткого написания абсолютного URL-адреса ASP.NET позволяет разработчикам страниц использовать тильду (~
) для указания корня веб-приложения. Например, ранее в этом руководстве я использовал нотацию ~/Admin/Default.aspx
в тексте для ссылки на страницу Default.aspx
в папке Admin
. Указывает ~
, что Admin
папка является вложенной папкой корневого каталога веб-приложения.
Метод Control
класса ResolveClientUrl
принимает URL-адрес и изменяет его на относительный URL-адрес, соответствующий веб-странице, на которой находится элемент управления. Например, при вызове ResolveClientUrl("~/Images/PoweredByASPNET.gif")
из возвращается About.aspx
Images/PoweredByASPNET.gif
. Однако при вызове из ~/Admin/Default.aspx
метода возвращается ../Images/PoweredByASPNET.gif
.
Примечание
Так как все ASP.NET серверные элементы управления являются производными Control
от класса , все серверные элементы управления имеют доступ к методу ResolveClientUrl
. Page
Даже класс является производным Control
от класса , что означает, что этот метод можно использовать непосредственно из ASP.NET классов кода программной части страниц.
Использование~
в декларативной разметке
Некоторые ASP.NET веб-элементов управления включают свойства, связанные с URL-адресом NavigateUrl
: элемент управления HyperLink имеет свойство , элемент управления Image имеет ImageUrl
свойство и т. д. При отображении эти элементы управления передают значения свойств, связанных с URL-адресом, в ResolveClientUrl
. Следовательно, если эти свойства содержат ~
для указания корня веб-приложения, URL-адрес будет изменен на допустимый относительный URL-адрес.
Имейте в виду, что только ASP.NET серверные элементы управления преобразуют ~
в свойствах, связанных с URL-адресом. ~
Если отображается в статической разметке HTML, например <img src="~/Images/PoweredByASPNET.gif" />
, подсистема ASP.NET отправляет ~
в браузер вместе с остальным html-содержимым. Браузер предполагает, что ~
является частью URL-адреса. Например, если браузер получает разметку <img src="~/Images/PoweredByASPNET.gif" />
, предполагается, что есть вложенная папка с именем ~
и вложенной папкой Images
, которая содержит файл PoweredByASPNET.gif
изображения .
Чтобы исправить разметку изображения в Site.master
, замените существующий <img>
элемент элементом управления ASP.NET Image Web. Задайте для элемента управления ID
Image Web значение PoweredByImage
, для его ImageUrl
свойства — ~/Images/PoweredByASPNET.gif
значение , а для свойства AlternateText
— значение "Питание от ASP.NET!"
<div id="footerContent">
<asp:Image ID="PoweredByImage" runat="server" ImageUrl="~/Images/PoweredByASPNET.gif"
AlternateText="Powered by ASP.NET!" />
</div>
После внесения этого изменения на страницу master снова вернитесь на страницу~/Admin/Default.aspx
. На этот PoweredByASPNET.gif
раз файл изображения появится на странице (см. рис. 3). При отрисовки элемента управления Image Web он использует ResolveClientUrl
метод для разрешения значения его ImageUrl
свойства. ImageUrl
В ~/Admin/Default.aspx
преобразуется в соответствующий относительный URL-адрес, как показано в следующем фрагменте кода ИСТОЧНИКА HTML:
<div id="footerContent">
<img id="ctl00_PoweredByImage" src="../Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>
Примечание
Помимо использования в свойствах веб-элемента управления на основе URL-адресов, ~
можно также использовать при вызове методов и Server.MapPath
, среди прочегоResponse.Redirect
. Кроме того, ResolveClientUrl
метод может вызываться непосредственно из ASP.NET или декларативной разметки страницы master.
Исправление оставшихся относительных URL-адресов главной страницы
В дополнение к элементу <img>
в footerContent
, который мы только что исправили, страница master содержит еще один относительный URL-адрес, который требует нашего внимания. Регион topContent
содержит ссылку "Учебники по эталонным страницам", которая указывает на Default.aspx
.
<div id="topContent">
<a href="Default.aspx">Master Pages Tutorials</a>
</div>
Так как этот URL-адрес является относительным, пользователь будет отправляться Default.aspx
на страницу в папке страницы содержимого, на который он находится. Чтобы эта ссылка всегда указывала Default.aspx
на в корневой папке, необходимо заменить <a>
элемент элементом управления HyperLink Web, чтобы можно было использовать ~
нотацию.
Удалите разметку <a>
элемента и добавьте вместо него элемент управления HyperLink. Задайте для параметра HyperLink ID
значение lnkHome
, для свойства NavigateUrl
~/Default.aspx
— значение , а для свойства Text
— значение "Учебники по эталонным страницам".
<div id="topContent">
<asp:HyperLink ID="lnkHome" runat="server" NavigateUrl="~/Default.aspx"
Text="Master Pages Tutorials" />
</div>
Вот и все! На этом этапе все URL-адреса на странице master правильно основаны при отображении страницы контента независимо от того, в каких папках находится страница master и страница содержимого.
Автоматическое разрешение URL-адресов в<head>
разделе
В учебнике Создание макета Site-Wide с помощью главных страниц мы добавили <link>
Styles.css
в файл в регионе <head>
:
<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>
<link>
Хотя атрибут элемента href
является относительным, он автоматически преобразуется в соответствующий путь во время выполнения. Как мы уже говорили в руководстве По указанию заголовка, метатегов и других заголовков HTML на главной странице , <head>
регион на самом деле является серверным элементом управления, который позволяет изменять содержимое внутренних элементов управления при отрисовке.
Чтобы проверить это, вернитесь на страницу ~/Admin/Default.aspx
и просмотрите html-источник, отправленный в браузер. Как показано в приведенном ниже фрагменте <link>
кода, атрибут элемента href
был автоматически изменен на соответствующий относительный URL-адрес . ../Styles.css
<head>
<title>
Default
</title>
<link href="../Styles.css" rel="stylesheet" type="text/css" />
</head>
Сводка
Эталонные страницы часто содержат ссылки, изображения и другие внешние ресурсы, которые необходимо указать с помощью URL-адреса. Так как страницы master и страницы содержимого могут не находиться в одной папке, важно воздержаться от использования относительных URL-адресов. Хотя можно использовать жестко закодированные абсолютные URL-адреса, это тесно связано с абсолютным URL-адресом веб-приложения. Если абсолютный URL-адрес меняется , как это часто происходит при перемещении или развертывании веб-приложения, вам придется не забывать вернуться и обновить абсолютные URL-адреса.
Идеальный подход — использовать тильду (~
), чтобы указать корень приложения. ASP.NET веб-элементы управления, содержащие свойства, связанные с URL-адресом ~
, сопоставляют с корнем приложения во время выполнения. Внутри веб-элементы управления используют Control
метод класса ResolveClientUrl
для создания допустимого относительного URL-адреса. Этот метод является общедоступным и доступен в каждом серверном элементе управления (включая Page
класс), поэтому при необходимости его можно использовать программно из классов программной части.
Счастливого программирования!
Дополнительные материалы
Дополнительные сведения о темах, рассмотренных в этом руководстве, см. в следующих ресурсах:
Об авторе
Скотт Митчелл(Scott Mitchell), автор нескольких книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 3,5 в 24 часа. Скотт может быть доступен в mitchell@4GuysFromRolla.com или через его блог по адресу http://ScottOnWriting.NET.
Особая благодарность
Хотите просмотреть предстоящие статьи MSDN? Если да, опустите мне строку на mitchell@4GuysFromRolla.com.