マスターページを使用した際のスクリプトファイルやスタイルシート、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.一番上位のマスターページの内のContentPlaceHolderの~(チルダ)は変換されない。

何か手はないだろうか。

・・・・・あった!!!

以下のように書けばいいみたい。

<script src="<%= this.ResolveClientUrl("~/Scripts/script.js") %>" type="text/javascript"></script>

変わらなかった部分を全て書き換えて実行してみた。

実行した結果・・・

全部変わったー!!!

よーし!

これで相対パスの問題は解決だー。

とりあえず~(チルダ)とthis.ResolveClientUrlを使えばなんとかなるな!

もう一つ注意点として、~(チルダ)が変換されるのはあくまでサーバーコントロール内で記載されているパスのみとのこと。

<a href=”~/WebForm2.aspx”></a>のようなただのHTMLコントロールでは変換されないので、気をつけよう。

コメントを残す

メールアドレスが公開されることはありません。