Adresy URL na stronach wzorcowych (C#)
Adresy URL na stronie wzorcowej mogą przerywać się ze względu na to, że plik strony wzorcowej jest w innym katalogu względnym niż strona zawartości. Analizuje ponownie adresy URL za pośrednictwem funkcji ~ w składni deklaratywnej i programowo używa metody ResolveUrl i ResolveClientUrl. (Przyjrzyj się również
Wprowadzenie
We wszystkich przykładach, które widzieliśmy do tej pory, strony wzorcowe i zawartości znajdują się w tym samym folderze (folder główny witryny internetowej). Nie ma jednak powodu, dla którego strony wzorcowe i zawartości muszą znajdować się w tym samym folderze. Na pewno można tworzyć strony zawartości w podfolderach. Podobnie możesz utworzyć folder, w ~/MasterPages/
którym umieszczasz strony wzorcowe witryny.
Jednym z potencjalnych problemów z umieszczaniem stron wzorcowych i zawartości w różnych folderach jest uszkodzenie adresów URL. Jeśli strona wzorcowa zawiera względne adresy URL w hiperlinkach, obrazach lub innych elementach, link będzie nieprawidłowy dla stron zawartości znajdujących się w innym folderze. W tym samouczku sprawdzimy źródło tego problemu, a także obejścia.
Problem z względnymi adresami URL
Adres URL na stronie internetowej jest wskazywany jako względny adres URL , jeśli lokalizacja zasobu, do którym wskazuje, jest względna względem lokalizacji strony internetowej w strukturze folderów witryny internetowej. Każdy adres URL, który nie zaczyna się od ukośnika wiodącego () lub protokołu (/
takiego jak http://
) jest względny, ponieważ jest rozpoznawany przez przeglądarkę na podstawie lokalizacji strony internetowej zawierającej adres URL.
Na przykład nasza witryna internetowa ma ~/Images/
folder z pojedynczym plikiem obrazu. PoweredByASPNET.gif
Plik Site.master
strony wzorcowej footerContent
ma <img>
element w regionie z następującymi znacznikami:
<div id="footerContent">
<img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>
Wartość src
atrybutu <img>
w elemecie jest względnym adresem URL, ponieważ nie zaczyna się od /
lub http://
. Krótko mówiąc, wartość atrybutu src
informuje przeglądarkę o wyszukaniu Images
w podfolderze pliku o nazwie PoweredByASPNET.gif
.
Podczas odwiedzania strony zawartości powyższe znaczniki są wysyłane bezpośrednio do przeglądarki. Poświęć chwilę, aby odwiedzić About.aspx
i wyświetlić źródło HTML wysłane do przeglądarki. Do przeglądarki wysłano dokładnie te same znaczniki na stronie wzorcowej.
<div id="footerContent">
<img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>
Jeśli strona zawartości znajduje się w folderze głównym (co jest About.aspx
) wszystko działa zgodnie z oczekiwaniami, ponieważ istnieje Images
podfolder względem folderu głównego. Jednak elementy można podzielić, jeśli strona zawartości znajduje się w innym folderze niż strona wzorcowa. Aby to zilustrować, utwórz podfolder o nazwie Admin
. Następnie dodaj stronę zawartości o nazwie Default.aspx
do Admin
folderu, aby powiązać nową stronę ze stroną wzorcową Site.master
.
Uwaga
W samouczku Określanie tytułu, tagów meta i innych nagłówków HTML na stronie wzorcowej utworzyliśmy niestandardową klasę strony podstawowej o nazwie BasePage
, która automatycznie ustawia tytuł strony zawartości (jeśli nie została jawnie przypisana). Nie zapomnij, aby nowo utworzona klasa za pomocą kodu strony pochodziła z tej funkcji, aby mogła korzystać z BasePage
tej funkcji.
Po utworzeniu tej strony zawartości Eksplorator rozwiązań powinny wyglądać podobnie do rysunku 1.
Rysunek 01. Dodano nowy folder i stronę ASP.NET do projektu
Następnie zaktualizuj Web.sitemap
plik, aby uwzględnić nowy <siteMapNode>
wpis dla tej lekcji. Poniższy kod XML przedstawia kompletny Web.sitemap
znacznik, który zawiera teraz dodanie trzeciego <siteMapNode>
elementu.
<?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>
Nowo utworzona Default.aspx
strona powinna mieć cztery kontrolki Zawartość odpowiadające czterem elementom ContentPlaceHolders w obiekcie Site.master
. Dodaj tekst do kontrolki Zawartość odwołującą MainContent
się do elementu ContentPlaceHolder, a następnie odwiedź stronę za pośrednictwem przeglądarki. Jak pokazano na rysunku PoweredByASPNET.gif
2, przeglądarka nie może odnaleźć pliku obrazu. Co się tu dzieje?
Strona ~/Admin/Default.aspx
zawartości jest wysyłana w tym samym kodzie HTML dla footerContent
regionu, co strona About.aspx
:
<div id="footerContent">
<img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>
<img>
Ponieważ atrybut elementu src
jest względnym adresem URL, przeglądarka próbuje wyszukać Images
folder względem lokalizacji folderu strony internetowej. Innymi słowy przeglądarka szuka pliku Admin/Images/PoweredByASPNET.gif
obrazu .
Rysunek 02. PoweredByASPNET.gif
Nie można odnaleźć pliku obrazu (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Zastępowanie względnych adresów URL bezwzględnymi adresami URL
Przeciwieństwem względnego adresu URL jest bezwzględny adres URL, który rozpoczyna się od ukośnika (/
) lub protokołu takiego jak http://
. Ponieważ bezwzględny adres URL określa lokalizację zasobu ze znanego punktu stałego, ten sam bezwzględny adres URL jest prawidłowy na dowolnej stronie internetowej, niezależnie od lokalizacji strony internetowej w strukturze folderów witryny sieci Web.
Aby rozwiązać problem z uszkodzonym obrazem pokazanym na rysunku 2, musimy zaktualizować <img>
atrybut elementu src
tak, aby używał bezwzględnego adresu URL zamiast względnego. Aby określić prawidłowy bezwzględny adres URL, odwiedź jedną ze stron internetowych w witrynie internetowej i sprawdź pasek adresowy. Jak pokazuje pasek adresowy na rysunku 2, w pełni kwalifikowana ścieżka do aplikacji internetowej to http://localhost:3908/ASPNET_MasterPages_Tutorial_04_CS/
. W związku z tym możemy zaktualizować <img>
atrybut elementu src
do jednego z następujących dwóch bezwzględnych adresów URL:
/ASPNET_MasterPages_Tutorial_04_CS/Images/PoweredByASPNET.gif
http://localhost:3908/ASPNET_MasterPages_Tutorial_04_CS/Images/PoweredByASPNET.gif
Poświęć chwilę, aby zaktualizować <img>
atrybut elementu src
do bezwzględnego adresu URL przy użyciu jednego z formularzy przedstawionych powyżej, a następnie odwiedź ~/Admin/Default.aspx
stronę za pośrednictwem przeglądarki. Tym razem przeglądarka będzie poprawnie znajdować i wyświetlać PoweredByASPNET.gif
plik obrazu (zobacz Rysunek 3).
Rysunek 03. Obraz PoweredByASPNET.gif
jest teraz wyświetlany (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Mimo że kodowanie w bezwzględnym adresie URL działa, ściśle łączy kod HTML z serwerem i lokalizacją folderu witryny internetowej, co może ulec zmianie. Użycie bezwzględnego adresu URL formularza http://localhost:3908/...
jest kruche, ponieważ numer portu poprzedniego localhost
jest wybierany automatycznie przy każdym uruchomieniu wbudowanego serwera internetowego ASP.NET Programistycznego programu Visual Studio. Podobnie część jest prawidłowa tylko podczas testowania http://localhost
lokalnego. Po wdrożeniu kodu na serwerze produkcyjnym baza adresów URL zmieni się na coś innego, na przykład http://www.yourserver.com
. Bezwzględny adres URL w postaci /ASPNET_MasterPages_Tutorial_04_CS/...
również cierpi na tę samą kruchość, ponieważ często ta ścieżka aplikacji różni się między serwerami deweloperskimi i produkcyjnymi.
Dobrą wiadomością jest to, że ASP.NET oferuje metodę generowania prawidłowego względnego adresu URL w czasie wykonywania.
Używanie i~
ResolveClientUrl
Zamiast kodować bezwzględny adres URL, ASP.NET umożliwia deweloperom stron używanie tyldy (~
) do wskazania katalogu głównego aplikacji internetowej. Na przykład wcześniej w tym samouczku użyto notacji ~/Admin/Default.aspx
w tekście, aby odwołać się do Default.aspx
strony w folderze Admin
. Wskazuje ~
, że Admin
folder jest podfolderem katalogu głównego aplikacji internetowej.
Control
Metoda klasy ResolveClientUrl
przyjmuje adres URL i modyfikuje go do względnego adresu URL odpowiedniego dla strony internetowej, na której znajduje się kontrolka. Na przykład wywołanie metody ResolveClientUrl("~/Images/PoweredByASPNET.gif")
z About.aspx
funkcji zwraca wartość Images/PoweredByASPNET.gif
. Wywołanie go z ~/Admin/Default.aspx
metody zwraca jednak wartość ../Images/PoweredByASPNET.gif
.
Uwaga
Ponieważ wszystkie kontrolki serwera ASP.NET pochodzą z Control
klasy, wszystkie mechanizmy kontroli serwera mają dostęp do ResolveClientUrl
metody . Page
Nawet klasa pochodzi z Control
klasy, co oznacza, że można użyć tej metody bezpośrednio z klas kodowych stron ASP.NET.
Używanie~
w deklaratywnej adiustacji
Kilka ASP.NET kontrolki sieci Web obejmują właściwości związane z adresem URL: kontrolka HyperLink ma właściwość; kontrolka Obraz ma NavigateUrl
ImageUrl
właściwość itd. Po renderowaniu te kontrolki przekazują wartości właściwości powiązanych z adresem URL do ResolveClientUrl
elementu . W związku z tym jeśli te właściwości zawierają element wskazujący ~
katalog główny aplikacji internetowej, adres URL zostanie zmodyfikowany na prawidłowy względny adres URL.
Należy pamiętać, że tylko ASP.NET kontrolki serwera przekształcają ~
właściwości związane z adresami URL. Jeśli element ~
pojawia się w statycznym znaczników HTML, takim jak <img src="~/Images/PoweredByASPNET.gif" />
, aparat ASP.NET wysyła ~
element do przeglądarki wraz z resztą zawartości HTML. W przeglądarce przyjęto założenie, że ~
element jest częścią adresu URL. Jeśli na przykład przeglądarka otrzyma znacznik <img src="~/Images/PoweredByASPNET.gif" />
zakłada, że istnieje podfolder o nazwie ~
z podfolderem Images
zawierającym plik PoweredByASPNET.gif
obrazu .
Aby naprawić znaczniki obrazu w pliku Site.master
, zastąp istniejący <img>
element kontrolką internetową obrazu ASP.NET. Ustaw dla kontrolki ID
PoweredByImage
Image Web wartość , jej ImageUrl
właściwość na ~/Images/PoweredByASPNET.gif
, a jej AlternateText
właściwość na "Obsługiwane przez ASP.NET!"
<div id="footerContent">
<asp:Image ID="PoweredByImage" runat="server" ImageUrl="~/Images/PoweredByASPNET.gif"
AlternateText="Powered by ASP.NET!" />
</div>
Po wprowadzeniu tej zmiany na stronie wzorcowej ponownie przejdź ~/Admin/Default.aspx
do strony. Tym razem PoweredByASPNET.gif
plik obrazu zostanie wyświetlony na stronie (zobacz Rysunek 3). Gdy kontrolka Obraz sieci Web jest renderowana, używa ResolveClientUrl
metody , aby rozpoznać jej ImageUrl
wartość właściwości. W ~/Admin/Default.aspx
pliku ImageUrl
jest konwertowany na odpowiedni względny adres URL, jak pokazano w poniższym fragmencie kodu HTML:
<div id="footerContent">
<img id="ctl00_PoweredByImage" src="../Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>
Uwaga
Oprócz korzystania z właściwości kontrolki sieci Web opartej na adresach URL, ~
można go również używać podczas wywoływania Response.Redirect
metod i Server.MapPath
, między innymi. ResolveClientUrl
Ponadto metoda może być wywoływana bezpośrednio z ASP.NET lub deklaratywnego znaczników strony wzorcowej.
Naprawianie pozostałych względnych adresów URL strony wzorcowej
Oprócz <img>
elementu w footerContent
tym, który właśnie naprawiliśmy, strona wzorcowa zawiera jeszcze jeden względny adres URL, który wymaga uwagi. Region topContent
zawiera link "Samouczki dotyczące stron wzorcowych", który wskazuje na Default.aspx
adres .
<div id="topContent">
<a href="Default.aspx">Master Pages Tutorials</a>
</div>
Ponieważ ten adres URL jest względny, wyśle użytkownika do Default.aspx
strony w folderze strony zawartości, którą odwiedza. Aby ten link zawsze wskazywał Default.aspx
w folderze głównym, należy zastąpić <a>
element kontrolką sieci Web funkcji HyperLink, aby można było użyć ~
notacji.
Usuń znaczniki <a>
elementu i dodaj kontrolkę HyperLink w swoim miejscu. Ustaw właściwość HyperLink ID
na lnkHome
, jej NavigateUrl
właściwość na ~/Default.aspx
, a jej Text
właściwość na "Samouczki stron wzorcowych".
<div id="topContent">
<asp:HyperLink ID="lnkHome" runat="server" NavigateUrl="~/Default.aspx"
Text="Master Pages Tutorials" />
</div>
Gotowe. W tym momencie wszystkie adresy URL na naszej stronie wzorcowej są prawidłowo oparte na renderowaniu przez stronę zawartości niezależnie od folderów, w których znajduje się strona wzorcowa i strona zawartości.
Automatyczne rozpoznawanie adresów<head>
URL w sekcji
W samouczku Tworzenie układu Site-Wide przy użyciu stron wzorcowych dodaliśmy element <link>
do Styles.css
pliku w <head>
regionie:
<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>
Atrybut elementu href
jest względny, ale jest on automatycznie konwertowany na odpowiednią ścieżkę w czasie wykonywania. Jak opisano w samouczku Określanie tytułu, tagów meta i innych nagłówków HTML na stronie wzorcowej , <head>
region jest w rzeczywistości kontrolką po stronie serwera, która umożliwia modyfikowanie zawartości jego kontrolek wewnętrznych podczas renderowania.
Aby to sprawdzić, przejdź ponownie do ~/Admin/Default.aspx
strony i wyświetl źródło HTML wysłane do przeglądarki. Jak pokazano w poniższym fragmencie kodu, <link>
atrybut elementu href
został automatycznie zmodyfikowany do odpowiedniego względnego adresu URL, ../Styles.css
.
<head>
<title>
Default
</title>
<link href="../Styles.css" rel="stylesheet" type="text/css" />
</head>
Podsumowanie
Strony wzorcowe często zawierają linki, obrazy i inne zasoby zewnętrzne, które muszą być określone za pośrednictwem adresu URL. Ponieważ strona wzorcowa i strony zawartości mogą nie istnieć w tym samym folderze, należy wstrzymać się od używania względnych adresów URL. Chociaż istnieje możliwość użycia zakodowanych bezwzględnych bezwzględnych adresów URL, w ten sposób ściśle łączy bezwzględny adres URL z aplikacją internetową. Jeśli bezwzględny adres URL ulegnie zmianie — tak jak często podczas przenoszenia lub wdrażania aplikacji internetowej — należy pamiętać, aby wrócić i zaktualizować bezwzględne adresy URL.
Idealnym rozwiązaniem jest użycie tyldy (~
) w celu wskazania katalogu głównego aplikacji. ASP.NET kontrolki sieci Web, które zawierają właściwości związane z adresem URL, mapuje ~
element na katalog główny aplikacji w czasie wykonywania. Wewnętrznie kontrolki Sieci Web używają Control
metody klasy do generowania ResolveClientUrl
prawidłowego względnego adresu URL. Ta metoda jest publiczna i dostępna z każdej kontrolki serwera (w tym Page
klasy), więc w razie potrzeby można jej używać programowo z klas za pomocą kodu.
Szczęśliwe programowanie!
Dalsze informacje
Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:
Informacje o autorze
Scott Mitchell, autor wielu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 3,5 w ciągu 24 godzin. Scott można dotrzeć pod mitchell@4GuysFromRolla.com adresem lub za pośrednictwem swojego bloga pod adresem http://ScottOnWriting.NET.
Specjalne podziękowania
Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.