マスターページを使用した際のスクリプトファイルやスタイルシート、href等の相対パスってどうなるんだろう?
マスターページからの相対パス?
それともWebフォームからの相対パス?
Webフォームからとなると階層の違うWebフォームがある場合、マスターページにはどのようなパスを記述したらいいんだろう?
気になったので、いろいろ調べていろいろ試してみた。
以下のフォルダ構成でテスト。

マスターページ「Site1.Master」に入れ子のマスターページ「NestedMasterPage1.master」を作成。
「NestedMasterPage1.master」をマスターページとして、「WebForm1.aspx」「WebForm2.aspx」を作成。
マスターページ内に記載された相対パスは実行時に実際のWebフォームからの相対パスに書き換えられるらしい。
相対パスを使って、script.js、Site.css、WebForm1.aspx、WebForm2.aspxへのリンクを以下のように記載してみた。
【Site1.Master】
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site1.master.cs" Inherits="WebApplication1.Sample.Site1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<!--Site1.master 開始-->
<script src="../Scripts/script.js" type="text/javascript"></script>
<link href="../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--Site1.master 終了-->
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<!--Site1.master 開始-->
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="WebForm1.aspx">WebForm1</asp:HyperLink>
<asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="../Sample2/Sample21/WebForm2.aspx">WebForm2</asp:HyperLink>
<!--Site1.master 終了-->
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
【NestedMasterPage1.master】
<%@ Master Language="C#" MasterPageFile="~/Sample/Site1.Master" AutoEventWireup="true"
CodeBehind="NestedMasterPage1.master.cs" Inherits="WebApplication1.Sample.NestedMasterPage1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<!--NestedMasterPage1.master 開始-->
<script src="../Scripts/script.js" type="text/javascript"></script>
<link href="../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--NestedMasterPage1.master 終了-->
<asp:ContentPlaceHolder ID="Nestedhead" runat="server"></asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<!--NestedMasterPage1.master 開始-->
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="WebForm1.aspx">WebForm1</asp:HyperLink>
<asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="../Sample2/Sample21/WebForm2.aspx">WebForm2</asp:HyperLink>
<!--NestedMasterPage1.master 終了-->
<asp:ContentPlaceHolder ID="NestedContentPlaceHolder1" runat="server"></asp:ContentPlaceHolder>
</asp:Content>
【WebForm1.aspx】
<%@ Page Title="" Language="C#" MasterPageFile="~/Sample/NestedMasterPage1.master"
AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.Sample.WebForm1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Nestedhead" runat="server">
<!--WebForm1.aspx 開始-->
<script src="../Scripts/script.js" type="text/javascript"></script>
<link href="../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--WebForm1.aspx 終了-->
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="NestedContentPlaceHolder1" runat="server">
<!--WebForm1.aspx 開始-->
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="WebForm1.aspx">WebForm1</asp:HyperLink>
<asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="../Sample2/Sample21/WebForm2.aspx">WebForm2</asp:HyperLink>
<!--WebForm1.aspx 終了-->
</asp:Content>
【WebForm2.aspx】
<%@ Page Title="" Language="C#" MasterPageFile="~/Sample/NestedMasterPage1.master"
AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="WebApplication1.Sample2.Sample21.WebForm2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Nestedhead" runat="server">
<!--WebForm2.aspx 開始-->
<script src="../../Scripts/script.js" type="text/javascript"></script>
<link href="../../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--WebForm2.aspx 終了-->
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="NestedContentPlaceHolder1" runat="server">
<!--WebForm2.aspx 開始-->
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="../../Sample/WebForm1.aspx">WebForm1</asp:HyperLink>
<asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="WebForm2.aspx">WebForm2</asp:HyperLink>
<!--WebForm2.aspx 終了-->
</asp:Content>
【実行したWebForm1.aspxのソース】
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<!--Site1.master 開始-->
<script src="../Scripts/script.js" type="text/javascript"></script>
<link href="../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--Site1.master 終了-->
<!--NestedMasterPage1.master 開始-->
<script src="../Scripts/script.js" type="text/javascript"></script>
<link href="../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--NestedMasterPage1.master 終了-->
<!--WebForm1.aspx 開始-->
<script src="../Scripts/script.js" type="text/javascript"></script>
<link href="../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--WebForm1.aspx 終了-->
</head>
<body>
<form method="post" action="WebForm1.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMTg0MzMwMDU2ZGTiSw70adm3ECCVM8grLanlWwO10ZEHFD/N9RZ5WsNe5Q==" />
</div>
<div>
<!--Site1.master 開始-->
<a id="HyperLink1" href="WebForm1.aspx">WebForm1</a>
<a id="HyperLink2" href="../Sample2/Sample21/WebForm2.aspx">WebForm2</a>
<!--Site1.master 終了-->
<!--NestedMasterPage1.master 開始-->
<a id="ContentPlaceHolder1_HyperLink1" href="WebForm1.aspx">WebForm1</a>
<a id="ContentPlaceHolder1_HyperLink2" href="../Sample2/Sample21/WebForm2.aspx">WebForm2</a>
<!--NestedMasterPage1.master 終了-->
<!--WebForm1.aspx 開始-->
<a id="ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink1" href="WebForm1.aspx">WebForm1</a>
<a id="ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink2" href="../Sample2/Sample21/WebForm2.aspx">WebForm2</a>
<!--WebForm1.aspx 終了-->
</div>
</form>
</body>
</html>
WebForm1.aspxのソースに関しては、マスターページも同じ階層にあるから、記述したパスと実行時のパスも全く一緒だね。
気になるのは次のWebForm2.aspxのソース。
確認してみる。
パスが変わってるところに★マークをつけてみた。
【実行したWebForm2.aspxのソース】
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<!--Site1.master 開始-->
<script src="../Scripts/script.js" type="text/javascript"></script>
★ <link href="../../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--Site1.master 終了-->
<!--NestedMasterPage1.master 開始-->
<script src="../Scripts/script.js" type="text/javascript"></script>
<link href="../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--NestedMasterPage1.master 終了-->
<!--WebForm2.aspx 開始-->
<script src="../../Scripts/script.js" type="text/javascript"></script>
<link href="../../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--WebForm2.aspx 終了-->
</head>
<body>
<form method="post" action="WebForm2.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMTg0MzMwMDU2ZGTJktGqFzpg+N5piwFRa8H6tb1fbs57vBnk5tlCg/+kFg==" />
</div>
<div>
<!--Site1.master 開始-->
★ <a id="HyperLink1" href="../../Sample/WebForm1.aspx">WebForm1</a>
★ <a id="HyperLink2" href="WebForm2.aspx">WebForm2</a>
<!--Site1.master 終了-->
<!--NestedMasterPage1.master 開始-->
★ <a id="ContentPlaceHolder1_HyperLink1" href="../../Sample/WebForm1.aspx">WebForm1</a>
★ <a id="ContentPlaceHolder1_HyperLink2" href="WebForm2.aspx">WebForm2</a>
<!--NestedMasterPage1.master 終了-->
<!--WebForm2.aspx 開始-->
<a id="ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink1" href="../../Sample/WebForm1.aspx">WebForm1</a>
<a id="ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink2" href="WebForm2.aspx">WebForm2</a>
<!--WebForm2.aspx 終了-->
</div>
</form>
</body>
</html>
おぉ。
aタグのhrefに関してはマスターページからの相対パスがちゃんとWebForm2.aspxからの相対パスに変わってる!
すげー。
でも、スクリプトファイルとスタイルシートのパスがそのままの部分があるなぁ。
いろいろ調べてみると~(チルダ)というものがあるらしい。
Web アプリケーションのルートを示すものらしいので、Webフォームの場所に関係なく相対パスを生成することができるみたい。
パスの部分を以下のように修正して、さっそく実行してみる。
<script src="~/Scripts/script.js" type="text/javascript"></script> <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Sample/WebForm1.aspx">WebForm1</asp:HyperLink> <asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="~/Sample2/Sample21/WebForm2.aspx">WebForm2</asp:HyperLink>
パスが変わってるところに★マークをつけてみた。
【実行したWebForm1.aspxのソース】
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<!--Site1.master 開始-->
<script src="~/Scripts/script.js" type="text/javascript"></script>
★ <link href="../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--Site1.master 終了-->
<!--NestedMasterPage1.master 開始-->
<script src="~/Scripts/script.js" type="text/javascript"></script>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<!--NestedMasterPage1.master 終了-->
<!--WebForm1.aspx 開始-->
<script src="~/Scripts/script.js" type="text/javascript"></script>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<!--WebForm1.aspx 終了-->
</head>
<body>
<form method="post" action="WebForm1.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMTg0MzMwMDU2ZGTiSw70adm3ECCVM8grLanlWwO10ZEHFD/N9RZ5WsNe5Q==" />
</div>
<div>
<!--Site1.master 開始-->
★ <a id="HyperLink1" href="WebForm1.aspx">WebForm1</a>
★ <a id="HyperLink2" href="../Sample2/Sample21/WebForm2.aspx">WebForm2</a>
<!--Site1.master 終了-->
<!--NestedMasterPage1.master 開始-->
★ <a id="ContentPlaceHolder1_HyperLink1" href="WebForm1.aspx">WebForm1</a>
★ <a id="ContentPlaceHolder1_HyperLink2" href="../Sample2/Sample21/WebForm2.aspx">WebForm2</a>
<!--NestedMasterPage1.master 終了-->
<!--WebForm1.aspx 開始-->
★ <a id="ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink1" href="WebForm1.aspx">WebForm1</a>
★ <a id="ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink2" href="../Sample2/Sample21/WebForm2.aspx">WebForm2</a>
<!--WebForm1.aspx 終了-->
</div>
</form>
</body>
</html>
【実行したWebForm2.aspxのソース】
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<!--Site1.master 開始-->
<script src="~/Scripts/script.js" type="text/javascript"></script>
★ <link href="../../Styles/Site.css" rel="stylesheet" type="text/css" />
<!--Site1.master 終了-->
<!--NestedMasterPage1.master 開始-->
<script src="~/Scripts/script.js" type="text/javascript"></script>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<!--NestedMasterPage1.master 終了-->
<!--WebForm2.aspx 開始-->
<script src="~/Scripts/script.js" type="text/javascript"></script>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<!--WebForm2.aspx 終了-->
</head>
<body>
<form method="post" action="WebForm2.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMTg0MzMwMDU2ZGTJktGqFzpg+N5piwFRa8H6tb1fbs57vBnk5tlCg/+kFg==" />
</div>
<div>
<!--Site1.master 開始-->
★ <a id="HyperLink1" href="../../Sample/WebForm1.aspx">WebForm1</a>
★ <a id="HyperLink2" href="WebForm2.aspx">WebForm2</a>
<!--Site1.master 終了-->
<!--NestedMasterPage1.master 開始-->
★ <a id="ContentPlaceHolder1_HyperLink1" href="../../Sample/WebForm1.aspx">WebForm1</a>
★ <a id="ContentPlaceHolder1_HyperLink2" href="WebForm2.aspx">WebForm2</a>
<!--NestedMasterPage1.master 終了-->
<!--WebForm2.aspx 開始-->
★ <a id="ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink1" href="../../Sample/WebForm1.aspx">WebForm1</a>
★ <a id="ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink2" href="WebForm2.aspx">WebForm2</a>
<!--WebForm2.aspx 終了-->
</div>
</form>
</body>
</html>
うーん。
変わってるところと変わってないところがある。
変わってるところをピックアップすると・・・
1.マスターページ「Site1.Master」の
内に記載したhref部分2.aタグのhref部分
他は変わらないなぁ。
なんでだろう。
いろいろ調べていると以下のようなルールがあることが判明。
1.scriptタグのsrcの~(チルダ)は変換されない。
2.一番上位のマスターページの
何か手はないだろうか。
・・・・・あった!!!
以下のように書けばいいみたい。
<script src="<%= this.ResolveClientUrl("~/Scripts/script.js") %>" type="text/javascript"></script>
変わらなかった部分を全て書き換えて実行してみた。
実行した結果・・・
全部変わったー!!!
よーし!
これで相対パスの問題は解決だー。
とりあえず~(チルダ)とthis.ResolveClientUrlを使えばなんとかなるな!
もう一つ注意点として、~(チルダ)が変換されるのはあくまでサーバーコントロール内で記載されているパスのみとのこと。
<a href=”~/WebForm2.aspx”></a>のようなただのHTMLコントロールでは変換されないので、気をつけよう。
