URL-адреса на эталонных страницах (C#)

Скотт Митчелл

Загрузить PDF-файл

Сведения о том, как МОГУТ прерываться 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.

В проект добавлены новая папка и страница ASP.NET

Рис. 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изображения .

Не удается найти файл изображения 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_CS/. Таким образом, можно обновить <img> атрибут элемента src на один из следующих двух абсолютных URL-адресов:

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

Найдите минутку, чтобы обновить <img> атрибут элемента src до абсолютного URL-адреса с помощью одной из приведенных выше форм, а затем посетите страницу ~/Admin/Default.aspx в браузере. На этот раз браузер правильно найдет и отобразит PoweredByASPNET.gif файл изображения (см. рис. 3).

Теперь отображается изображение PoweredByASPNET.gif

Рис. 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_CS/... также страдает от той же хрупкости, так как часто этот путь приложения отличается между серверами разработки и рабочей средой.

Хорошей новостью является то, что ASP.NET предлагает метод для создания допустимого относительного URL-адреса во время выполнения.

Использование~иResolveClientUrl

Вместо жесткого написания абсолютного URL-адреса ASP.NET позволяет разработчикам страниц использовать тильду (~) для указания корня веб-приложения. Например, ранее в этом руководстве я использовал нотацию ~/Admin/Default.aspx в тексте для ссылки на страницу Default.aspx в папке Admin . Указывает ~ , что Admin папка является вложенной папкой корневого каталога веб-приложения.

Метод Control класса ResolveClientUrl принимает URL-адрес и изменяет его на относительный URL-адрес, соответствующий веб-странице, на которой находится элемент управления. Например, при вызове ResolveClientUrl("~/Images/PoweredByASPNET.gif") из возвращается About.aspxImages/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.