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

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

Скачать в формате PDF

Определяет, как URL-адреса мастер-страницы могут быть ошибочными из-за того, что файл мастер-страницы находится в другом относительном каталоге по сравнению с файлом страницы содержимого. Просматривает изменение базовых URL-адресов с использованием ~ в декларативном синтаксисе и программном использовании функций ResolveUrl и ResolveClientUrl. (Также посмотрите на

Введение

Во всех примерах, которые мы видели до сих пор, главные и страницы содержимого находятся в одной папке (корневой папке веб-сайта). Но нет причин, почему главные и контентные страницы должны находиться в той же папке. Вы, безусловно, можете создавать страницы содержимого в вложенных папках. Аналогичным образом можно создать папку ~/MasterPages/ , в которой размещаются главные страницы сайта.

Одна из потенциальных проблем с размещением главных страниц и страниц содержимого в разных папках включает сломанные URL-адреса. Если эталонная страница содержит относительные URL-адреса в гиперссылках, изображениях или других элементах, ссылка будет недопустимой для страниц содержимого, которые находятся в другой папке. В этом руководстве мы рассмотрим источник этой проблемы, а также обходные пути.

Проблема с относительными URL-адресами

URL-адрес веб-страницы считается относительным, если расположение ресурса, на который он указывает, соответствует расположению веб-страницы в структуре папок веб-сайта. Любой URL-адрес, который не начинается с косой черты в начале (/например, протокол http://) является относительным, так как он разрешается браузером в зависимости от расположения веб-страницы, содержащей URL-адрес.

Например, на нашем веб-сайте есть папка ~/Images/ с единственным файлом изображения PoweredByASPNET.gif. Файл главной страницы Site.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-исходный код, отправленный в браузер. Вы увидите, что та же разметка в мастер-странице была передана в браузер.

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

Если страница содержимого находится в корневой папке (как и About.aspx) все работает должным образом, так как Images есть вложенная папка относительно корневой папки. Однако, если страница содержимого находится в папке, отличающейся от той, где расположена мастер-страница, происходит сбой в работе. Чтобы проиллюстрировать это, создайте вложенную папку с именем Admin. Затем добавьте страницу содержимого с именем Default.aspxAdmin в папку, чтобы привязать новую страницу к главной Site.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 Добавьте текст в управляющий элемент "Content", который ссылается на 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 выбирается автоматически при каждом запуске встроенного в Visual Studio веб-сервера разработки ASP.NET. Аналогичным образом часть http://localhost действительна только при локальном тестировании. После развертывания кода на рабочем сервере база URL-адресов изменится на что-то другое, например http://www.yourserver.com. Абсолютный URL-адрес в форме /ASPNET_MasterPages_Tutorial_04_CS/... также страдает от той же хрупкости, так как часто этот путь приложения отличается между серверами разработки и рабочей среды.

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

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

ASP.NET позволяет вместо жесткого кодирования абсолютного URL-адреса использовать тильду (~) для указания корня веб-приложения. Например, ранее в этом руководстве я использовал нотацию ~/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-адресом: элемент управления HyperLink имеет свойство NavigateUrl; элемент управления 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 control свойство ID в значение PoweredByImage, его свойство ImageUrl в значение ~/Images/PoweredByASPNET.gif, а свойство AlternateText в значение "Powered by ASP.NET!"

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

После внесения этого изменения в мастер-страницу снова посетите страницу ~/Admin/Default.aspx. На этот раз PoweredByASPNET.gif файл изображения появится на странице (см. рис. 3). При визуализации веб-элемента управления Image используется метод ResolveClientUrl для определения значения свойства ImageUrl. ~/Admin/Default.aspx В элементе ImageUrl преобразуется в соответствующий относительный URL-адрес, как показано в следующем фрагменте HTML-кода:

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

Замечание

Помимо использования в свойствах веб-элемента управления на основе URL-адресов, ~ также можно использовать при вызове методов Response.Redirect и Server.MapPath, среди прочего. Кроме того, ResolveClientUrl метод может вызываться непосредственно из декларативной разметки ASP.NET или главной страницы.

Исправление оставшихся URL-адресов главной страницы

Помимо элемента <img>, который мы только что исправили, основная страница также содержит еще один относительный URL, требующий нашего внимания. Регион topContent содержит ссылку "Руководства по главным страницам", направляющую на Default.aspx.

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

Так как этот URL-адрес является относительным, он приведет пользователя на страницу Default.aspx в папке страницы содержимого, которую они посещают. Чтобы эта ссылка всегда указывала Default.aspx на корневую папку, необходимо заменить <a> элемент веб-элементом управления HyperLink, чтобы мы могли использовать нотацию ~ .

Удалите разметку <a> элемента и добавьте элемент управления HyperLink на его месте. Задайте для элемента hyperLink свойство ID на lnkHome, свойство NavigateUrl на ~/Default.aspx, и свойство Text — на "Master Pages Tutorials".

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

Вот и все! На этом этапе все URL-адреса на главной странице правильно настроены при рендеринге на странице содержимого, независимо от того, в каких папках расположены главная страница и страница содержимого.

Автоматическое<head>разрешение URL-адресов в разделе

В руководстве по созданию макета 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-адресу. Так как эталонная страница и страницы содержимого могут не существовать в той же папке, важно воздержаться от использования относительных URL-адресов. Хотя можно использовать жёстко закодированные абсолютные URL-адреса, это тесно связывает абсолютный URL-адрес с веб-приложением. Если абсолютный URL-адрес изменяется, что часто бывает при перемещении или развертывании веб-приложения, вам придется не забыть вернуться и обновить абсолютные URL-адреса.

Идеальным подходом является использование тильды (~) для указания корня приложения. ASP.NET веб-элементы управления, которые содержат свойства, связанные с URL-адресом, отображают ~ на корень приложения во время выполнения. Элементы управления веба используют метод класса Control для создания допустимого относительного URL-адреса. Этот метод является общедоступным и доступен для каждого серверного элемента управления (включая класс Page), поэтому при необходимости его можно использовать программно из бэкэнд-классов.

Счастливое программирование!

Дальнейшее чтение

Дополнительные сведения о разделах, описанных в этом руководстве, см. в следующих ресурсах:

Об авторе

Скотт Митчелл, автор нескольких книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 3.5 за 24 часа. С Скоттом можно связаться на mitchell@4GuysFromRolla.com или через его блог http://ScottOnWriting.NET.

Особое спасибо кому

Хотите просмотреть мои предстоящие статьи MSDN? Если да, напишите мне на mitchell@4GuysFromRolla.com.