次の方法で共有


マスター ページの URL (C#)

作成者: Scott Mitchell

PDF のダウンロード

マスター ページ ファイルがコンテンツ ページとは異なる相対ディレクトリに存在することにより、マスター ページ内の URL が壊れる可能性があることについて説明します。 宣言構文で ~ を介して URL をリベースする方法と、ResolveUrl と ResolveClientUrl をプログラムで使用する方法について説明します。 (また、次を参照してください。

はじめに

これまでに見てきたすべての例では、マスター ページとコンテンツ ページは同じフォルダー (Web サイトのルート フォルダー) に配置されていました。 しかし、マスター ページとコンテンツ ページが同じフォルダー内に存在すべき理由はありません。 サブフォルダーにコンテンツ ページを作成しても問題ありません。 同様に、~/MasterPages/ フォルダーを作成して、そこにサイトのマスター ページを配置することもできます。

マスター ページとコンテンツ ページを異なるフォルダーに配置する場合の潜在的な問題の 1 つは、URL の破損です。 マスター ページ内のハイパーリンク、画像、またはその他の要素に相対 URL が含まれている場合、別のフォルダー内のコンテンツ ページのリンクは無効になります。 このチュートリアルでは、この問題の原因と回避策について説明します。

相対 URL に関する問題

Web ページ上の URL は、それが指定するリソースの場所が Web サイトのフォルダー構造における Web ページの場所を基準とする場合に、"相対 URL" と呼ばれます。 先頭がスラッシュ (/) やプロトコル (http:// など) で始まらない URL は、URL を含む Web ページの場所に基づいてブラウザーによって解決されるため、相対 URL です。

たとえば、ここでの Web サイトには、1 つの画像ファイル PoweredByASPNET.gif が入った ~/Images/ フォルダーがあります。 マスター ページ ファイル Site.masterfooterContent 領域には、以下のマークアップを含む <img> 要素があります。

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

<img> 要素内の src 属性値は、先頭が / または http:// ではないため、相対 URL です。 つまり、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 という名前のサブフォルダーを作成します。 次に、Admin フォルダーに Default.aspx という名前のコンテンツ ページを追加し、新しいページを Site.master マスター ページにバインドします。

Note

マスター ページでタイトル、メタ タグ、その他の HTML ヘッダーを指定する」チュートリアルでは、コンテンツ ページのタイトルを (それが明示的に割り当てられていない場合に) 自動的に設定する、BasePage という名前のカスタム ベース ページ クラスを作成しました。 この機能を利用できるように、忘れずに新しく作成されたページの分離コード クラスを BasePage から派生させるようにしてください。

このコンテンツ ページを作成すると、ソリューション エクスプローラーは図 1 のようになります。

A New Folder and ASP.NET Page Have Been Added to the Project

図 01: 新しいフォルダーと ASP.NET ページがプロジェクトに追加されました

次に、この新しい <siteMapNode> エントリを含むように Web.sitemap ファイルを更新します。 以下の XML は、3 つめの <siteMapNode> 要素が追加された完全な Web.sitemap マークアップを示しています。

<?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 ページには、Site.master の 4 つの ContentPlaceHolders に対応する 4 つの Content コントロールがあります。 MainContent ContentPlaceHolder を参照している Content コントロールに何らかのテキストを追加し、ブラウザーからページにアクセスします。 図 2 に示すように、ブラウザーは PoweredByASPNET.gif 画像ファイルを見つけることができません。 どうなっているのでしょうか?

~/Admin/Default.aspx コンテンツ ページには、About.aspx ページと同じ HTML が footerContent 領域に送信されます。

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

<img> 要素の src 属性は相対 URL であるため、ブラウザーは Web ページのフォルダーの場所を基準に Images フォルダーを探そうとします。 言い換えると、ブラウザーは画像ファイル Admin/Images/PoweredByASPNET.gif を探しています。

The PoweredByASPNET.gif Image File Cannot Be Found

図 02: PoweredByASPNET.gif 画像ファイルが見つかりません (クリックするとフルサイズの画像が表示されます)

相対 URL を絶対 URL に置き換える

相対 URL の反対は "絶対 URL" で、スラッシュ (/) や http:// のようなプロトコルで始まります。 絶対 URL は既知の固定ポイントからのリソースの場所を指定するため、Web サイトのフォルダー構造における Web ページの場所に関係なく、同じ絶対 URL はどの Web ページでも有効です。

図 2 に示されている破損した画像を修正するには、<img> 要素の src 属性を更新して、相対 URL ではなく絶対 URL を使用するようにする必要があります。 正しい絶対 URL を判断するには、Web サイトのいずれかの Web ページにアクセスし、アドレス バーを調べます。 図 2 のアドレス バーが示すように、Web アプリケーションへの完全修飾パスは http://localhost:3908/ASPNET_MasterPages_Tutorial_04_CS/ です。 そのため、<img> 要素の src 属性を以下の 2 つの絶対 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 を参照)。

The PoweredByASPNET.gif Image is Now Displayed

図 03: PoweredByASPNET.gif 画像が表示されるようになりました (クリックするとフルサイズの画像が表示されます)

絶対 URL のハード コーディングは機能しますが、HTML が、変更される可能性のある Web サイトのサーバーやフォルダーの場所に密接に結び付いてしまいます。 http://localhost:3908/... という形式の絶対 URL を使用することは危険です。localhost の前のポート番号は、Visual Studio の組み込み ASP.NET 開発 Web サーバーが起動されるたびに自動的に選択されるからです。 同様に、http://localhost の部分はローカルでテストする場合のみ有効です。 コードが運用サーバーに配置されると、URL ベースは http://www.yourserver.com のような別のものに変更されます。 形式 /ASPNET_MasterPages_Tutorial_04_CS/... の絶対 URL も、開発サーバーと運用サーバーでこのアプリケーション パスが異なる場合が多いため、同じく不安定です。

幸いなことに、ASP.NET には実行時に有効な相対 URL を生成するためのメソッドが用意されています。

~ResolveClientUrl を使用する

ASP.NET では、絶対 URL をハード コーディングする代わりに、ページ開発者はチルダ (~) を使用して Web アプリケーションのルートを示すことができます。 たとえば、このチュートリアルの前半では、テキスト内で ~/Admin/Default.aspx 表記を使用して Admin フォルダー内の Default.aspx ページを参照しました。 ~ は、Admin フォルダーが Web アプリケーションのルートのサブフォルダーであることを示します。

Control クラスの ResolveClientUrl メソッドは、URL をコントロールが存在する Web ページに適した相対 URL に変更します。 たとえば、About.aspx から ResolveClientUrl("~/Images/PoweredByASPNET.gif") を呼び出すと、Images/PoweredByASPNET.gif が返されます。 しかし、~/Admin/Default.aspx から呼び出すと、../Images/PoweredByASPNET.gif が返されます。

Note

すべての ASP.NET サーバー コントロールは Control クラスから派生するため、すべてのサーバー コントロールが ResolveClientUrl メソッドにアクセスできます。 Page クラスも Control クラスから派生するため、ASP.NET ページの分離コード クラスから直接このメソッドを使用できます。

宣言型マークアップで ~ を使用する

ASP.NET のいくつかの Web コントロールには、URL 関連のプロパティが含まれます。たとえば、HyperLink コントロールには NavigateUrl プロパティがあり、Image コントロールには ImageUrl プロパティがあります。 これらのコントロールは、レンダリング時に URL 関連のプロパティ値を ResolveClientUrl に渡します。 したがって、これらのプロパティに Web アプリケーションのルートを示す ~ が含まれている場合、URL は有効な相対 URL に変更されます。

ASP.NET サーバー コントロールのみが、URL 関連のプロパティの ~ を変換することに注意してください。 <img src="~/Images/PoweredByASPNET.gif" /> のように静的 HTML マークアップに ~ がある場合、ASP.NET エンジンは ~ を残りの HTML コンテンツと共にブラウザーに送信します。 ブラウザーは、~ を URL の一部と見なします。 たとえば、ブラウザーが <img src="~/Images/PoweredByASPNET.gif" /> というマークアップを受け取った場合、画像ファイル PoweredByASPNET.gif を含む サブフォルダー Images が含まれた ~ というサブフォルダーが存在すると推測されます。

Site.master の画像マークアップを修正するには、既存の <img> 要素を ASP.NET Image Web コントロールに置き換えます。 Image Web コントロールの IDPoweredByImage に設定し、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 Web コントロールがレンダリングされると、ResolveClientUrl メソッドを使用して ImageUrl プロパティ値が解決されます。 以下の HTML ソースのスニペットが示すように、~/Admin/Default.aspx では ImageUrl が適切な相対 URL に変換されます。

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

Note

URL ベースの Web コントロール プロパティで使用されるだけでなく、~Response.Redirect メソッドや Server.MapPath メソッドなどを呼び出すときにも使用できます。 また、ResolveClientUrl メソッドは、ASP.NET またはマスター ページの宣言型マークアップから直接呼び出すこともできます。

マスター ページの残りの相対 URL を修正する

マスター ページには、修正した footerContent 内の <img> 要素に加えて、注意が必要な相対 URL がもう 1 つあります。 topContent 領域には、Default.aspx を指す「Master Pages Tutorials」というリンクが含まれています。

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

この URL は相対 URL であるため、アクセスしているコンテンツ ページのフォルダー内の Default.aspx ページにユーザーを移動させます。 このリンクがルート フォルダー内の Default.aspx を常に指すようにするには、~ 表記を使用できるように、<a> 要素を HyperLink Web コントロールに置き換える必要があります。

<a> 要素のマークアップを削除し、その場所に HyperLink コントロールを追加します。 HyperLink コントロールの IDlnkHome に設定し、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 の自動解決

マスター ページを利用してサイト全体レイアウトを作成する」チュートリアルでは、<head> 領域内の Styles.css ファイルに <link> を追加しました。

<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 が Web アプリケーションに密に結び付いてしまいます。 絶対 URL が変わった場合は (Web アプリケーションの移動や配置時によくあります)、必ず前に戻って絶対 URL を更新する必要があります。

理想的な方法は、チルダ (~) を使用してアプリケーション ルートを示すことです。 URL 関連のプロパティを含む ASP.NET Web コントロールによって、~ は実行時にアプリケーション ルートにマップされます。 内部的には、Web コントロールによって Control クラスの ResolveClientUrl メソッドを使用して有効な相対 URL が生成されます。 このメソッドはパブリック メソッドであり、すべてのサーバー コントロール (Page クラスを含む) から使用できるため、必要に応じて分離コード クラスからプログラムで使用できます。

プログラミングに満足!

もっと読む

この記事で説明したトピックの詳細については、次のリソースを参照してください。

作成者について

複数の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の著書は、『Sams Teach Yourself ASP.NET 3.5 in 24 Hours』です。 Mitchell 氏には、mitchell@4GuysFromRolla.com から、または http://ScottOnWriting.NET で彼のブログを介して連絡できます。

特別な感謝

今後の MSDN の記事を確認することに関心がありますか? ご希望の場合は、mitchell@4GuysFromRolla.com までメッセージをお送りください。