Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Autor : Scott Mitchell
Jak adresy URL na stronie wzorcowej mogą przestać działać z powodu tego, że plik strony wzorcowej znajduje się w innym katalogu względnym niż strona z treścią. Sprawdza podstawianie adresów URL przy użyciu znaku ~ w składni deklaratywnej, a w sposób programowy za pomocą metody ResolveUrl i ResolveClientUrl. (Przyjrzyj się również
Introduction
We wszystkich przykładach, które widzieliśmy do tej pory, strony główne i zawartości znajdują się w tym samym folderze (folderze głównym). Nie ma jednak powodu, dla którego strony wzorcowe i strony z 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 przeanalizujemy źródło tego problemu, a także obejścia.
Problem z względnymi adresami URL
Adres URL strony internetowej jest określany jako względny adres URL , jeśli lokalizacja zasobu, do którym wskazuje, jest względna w stosunku do lokalizacji strony internetowej w strukturze folderów witryny sieci Web. Każdy adres URL, który nie rozpoczyna 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 zawiera ~/Images/ folder z pojedynczym plikiem obrazu. PoweredByASPNET.gif Plik strony wzorcowej Site.master ma element <img> w regionie footerContent z następującym znacznikiem:
<div id="footerContent">
<img src="Images/PoweredByASPNET.gif" alt="Powered by ASP.NET!" />
</div>
Wartość src atrybutu w elemecie <img> jest względnym adresem URL, ponieważ nie zaczyna się od / lub http://. Krótko mówiąc, wartość atrybutu src informuje przeglądarkę, aby szukała w podfolderze Images pliku o nazwie PoweredByASPNET.gif.
Podczas odwiedzania strony zawartości powyższy znacznik jest wysyłany bezpośrednio do przeglądarki. Poświęć chwilę, aby odwiedzić About.aspx i wyświetlić źródło HTML wysłane do przeglądarki. Przekonasz się, że te same znaczniki w stronie głównej zostały wysłane do przeglądarki.
<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 (podobnie jak About.aspx) wszystko działa zgodnie z oczekiwaniami, ponieważ istnieje Images podfolder względem folderu głównego. Jednak pojawiają się problemy, 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 / Notatka
W samouczku Określanie tytułu, tagów meta i innych nagłówków HTML na stronie wzorcowej utworzyliśmy niestandardową klasę strony bazowej o nazwie BasePage , która automatycznie ustawia tytuł strony zawartości (jeśli nie została jawnie przypisana). Nie zapomnij, aby klasa zaplecza nowo utworzonej strony dziedziczyła z BasePage, aby mogła korzystać z tej funkcjonalności.
Po utworzeniu tej strony zawartości Eksplorator rozwiązań powinien wyglądać podobnie do rysunku 1.
Rysunek 01. Do projektu dodano nowy folder i stronę ASP.NET
Następnie zaktualizuj Web.sitemap plik, aby uwzględnić nowy <siteMapNode> wpis dla tej lekcji. Poniższy kod XML przedstawia pełny 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 zawierać cztery kontrolki zawartości odpowiadające czterem miejscom ContentPlaceHolders w elemencie Site.master. Dodaj tekst do kontrolki zawartości, który odwołuje się do elementu MainContent ContentPlaceHolder, a następnie otwórz stronę w przeglądarce. 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 otrzymuje ten sam kod HTML dla footerContent obszaru, 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 obrazu Admin/Images/PoweredByASPNET.gif.
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 stałego punktu, 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 adresów. Jak pokazuje pasek adresowy na rysunku 2, w pełni kwalifikowana ścieżka do aplikacji internetowej to http://localhost:3908/ASPNET_MasterPages_Tutorial_04_VB/. 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_VB/Images/PoweredByASPNET.gifhttp://localhost:3908/ASPNET_MasterPages_Tutorial_04_VB/Images/PoweredByASPNET.gif
Pośmiń chwilę na zaktualizowanie atrybutu <img> 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 poprawnie znajdzie i wyświetli PoweredByASPNET.gif plik obrazu (zobacz Rysunek 3).
Rysunek 03. PoweredByASPNET.gif Obraz jest teraz wyświetlany (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Twarde kodowanie bezwzględnego adresu URL działa, ale powoduje ścisłe powiązanie kodu HTML z serwerem i lokalizacją folderu witryny, co może się zmienić. Użycie bezwzględnego adresu URL formularza http://localhost:3908/... jest kruche, ponieważ numer portu poprzedzającego hosta lokalnego jest wybierany automatycznie przy każdym uruchomieniu wbudowanego serwera internetowego ASP.NET programistycznego programu Visual Studio. Podobnie, część http://localhost jest prawidłowa tylko podczas lokalnego testowania. 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_VB/... 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 folder Admin 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 ResolveClientUrl("~/Images/PoweredByASPNET.gif") z About.aspx zwraca Images/PoweredByASPNET.gif. Wywołanie go z ~/Admin/Default.aspx jednak zwraca ../Images/PoweredByASPNET.gif.
Uwaga / Notatka
Ponieważ wszystkie kontrolki serwera ASP.NET pochodzą z Control klasy, wszystkie kontrolki serwera mają dostęp do ResolveClientUrl metody .
Page klasa dziedziczy z klasy Control, co oznacza, że można używać tej metody bezpośrednio w klasach zaplecza kodu stron ASP.NET.
Używanie~w deklaratywnej notacji.
Kilka ASP.NET kontrolki sieci Web obejmują właściwości związane z adresem URL: kontrolka HyperLink ma NavigateUrl właściwość; kontrolka Obraz ma ImageUrl właściwość itd. Po wyrenderowaniu 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ą ~, aby wskazać katalog główny aplikacji internetowej, adres URL zostanie zmieniony na prawidłowy względny adres.
Należy pamiętać, że tylko kontrolki serwera ASP.NET przekształcają element ~ we właściwościach związanych z adresem URL. Jeśli element ~ pojawi się w statycznym znaczniku HTML, takim jak na przykład <img src="~/Images/PoweredByASPNET.gif" />, silnik ASP.NET wysyła ~ 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 odbierze znacznik <img src="~/Images/PoweredByASPNET.gif" /> zakłada, że istnieje podfolder o nazwie ~ z podfolderem Images zawierającym plik PoweredByASPNET.gifobrazu .
Aby naprawić znacznik obrazu w pliku Site.master, zastąp istniejący <img> element kontrolką internetową obrazu ASP.NET. Ustaw kontrolkę obrazu sieci Web ID na PoweredByImage, właściwość ImageUrl na ~/Images/PoweredByASPNET.gif, a właściwość AlternateText na "Powered by 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 odwiedź ponownie stronę ~/Admin/Default.aspx. Tym razem PoweredByASPNET.gif plik obrazu pojawi się na stronie (zobacz Rysunek 3). Gdy kontrolka obrazu w sieci Web jest renderowana, używa metody ResolveClientUrl do ustawiania wartości swojej właściwości ImageUrl. W ~/Admin/Default.aspxImageUrl jest konwertowany na odpowiedni relatywny 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 / Notatka
Oprócz użycia we właściwościach kontrolki sieci Web opartej na adresach URL, można go również używać podczas wywoływania metod Response.Redirect 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.
Korygowanie pozostałych względnych adresów URL strony wzorcowej
Oprócz elementu <img> w footerContent, który właśnie naprawiliśmy, strona wzorcowa zawiera jeszcze jeden względny adres URL, który wymaga naszej uwagi. Region topContent zawiera link "Samouczki dotyczące stron wzorcowych", który wskazuje na Default.aspx.
<div id="topContent">
<a href="Default.aspx">Master Pages Tutorials</a>
</div>
Ponieważ ten adres URL jest względny, użytkownik zostanie wysłany 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ć element <a> kontrolką HyperLink Web, aby można było użyć notacji ~.
Usuń znaczniki <a> elementu i dodaj kontrolkę HyperLink w jego miejsce. 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>
To wszystko! W tym momencie wszystkie adresy URL na naszej stronie wzorcowej są poprawnie przetwarzane przy renderowaniu przez stronę zawartości, niezależnie od tego, w jakich folderach znajdują 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>
Atrybut elementu href jest względny, ale podczas wykonywania jest automatycznie konwertowany na odpowiednią ścieżkę. Jak omówiliśmy w samouczku Określanie tytułu, tagów meta i innych nagłówków HTML na stronie wzorcowej, <head> region to kontrolka po stronie serwera, która może modyfikować zawartość swoich wewnętrznych kontrolek w trakcie renderowania.
Aby to sprawdzić, ponownie zapoznaj się ze ~/Admin/Default.aspx stroną i wyświetl źródło HTML wysłane do przeglądarki. Jak widać w poniższym fragmencie kodu, atrybut <link> elementu href został automatycznie zmodyfikowany na odpowiedni względny adres 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ż strony wzorcowe i strony zawartości mogą nie istnieć w tym samym folderze, ważne jest, aby powstrzymać się od używania względnych adresów URL. Chociaż istnieje możliwość użycia zakodowanych bezwzględnych adresów URL, takie działanie ś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. Kontrolki sieci Web ASP.NET, które zawierają właściwości związane z adresem URL, przypisują element ~ do katalogu głównego aplikacji podczas działania. Wewnętrznie kontrolki sieci Web używają metody klasy Control do generowania prawidłowego względnego adresu URL ResolveClientUrl. Ta metoda jest publiczna i dostępna z każdej kontrolki serwera (w tym klasy Page), więc można jej używać programowo w klasach kodu-bezpośredniego, w razie potrzeby.
Szczęśliwe programowanie!
Dalsza lektura
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. Z Scottem można skontaktować się pod mitchell@4GuysFromRolla.com lub poprzez jego blog pod adresem http://ScottOnWriting.NET.
Specjalne podziękowania
Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.