マスターページを使用した際のスクリプトファイルやスタイルシート、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】
1 | <%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site1.master.cs" Inherits="WebApplication1.Sample.Site1" %> |
8 | < script src = "../Scripts/script.js" type = "text/javascript" ></ script > |
9 | < link href = "../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
11 | < asp:ContentPlaceHolder ID = "head" runat = "server" > |
12 | </ asp:ContentPlaceHolder > |
15 | < form id = "form1" runat = "server" > |
18 | < asp:HyperLink ID = "HyperLink1" runat = "server" NavigateUrl = "WebForm1.aspx" >WebForm1</ asp:HyperLink > |
19 | < asp:HyperLink ID = "HyperLink2" runat = "server" NavigateUrl = "../Sample2/Sample21/WebForm2.aspx" >WebForm2</ asp:HyperLink > |
21 | < asp:ContentPlaceHolder ID = "ContentPlaceHolder1" runat = "server" > |
22 | </ asp:ContentPlaceHolder > |
【NestedMasterPage1.master】
1 | <%@ Master Language="C#" MasterPageFile="~/Sample/Site1.Master" AutoEventWireup="true" |
2 | CodeBehind="NestedMasterPage1.master.cs" Inherits="WebApplication1.Sample.NestedMasterPage1" %> |
4 | < asp:Content ID = "Content1" ContentPlaceHolderID = "head" runat = "server" > |
6 | < script src = "../Scripts/script.js" type = "text/javascript" ></ script > |
7 | < link href = "../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
9 | < asp:ContentPlaceHolder ID = "Nestedhead" runat = "server" ></ asp:ContentPlaceHolder > |
11 | < asp:Content ID = "Content2" ContentPlaceHolderID = "ContentPlaceHolder1" runat = "server" > |
13 | < asp:HyperLink ID = "HyperLink1" runat = "server" NavigateUrl = "WebForm1.aspx" >WebForm1</ asp:HyperLink > |
14 | < asp:HyperLink ID = "HyperLink2" runat = "server" NavigateUrl = "../Sample2/Sample21/WebForm2.aspx" >WebForm2</ asp:HyperLink > |
16 | < asp:ContentPlaceHolder ID = "NestedContentPlaceHolder1" runat = "server" ></ asp:ContentPlaceHolder > |
【WebForm1.aspx】
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Sample/NestedMasterPage1.master" |
2 | AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.Sample.WebForm1" %> |
4 | < asp:Content ID = "Content1" ContentPlaceHolderID = "Nestedhead" runat = "server" > |
6 | < script src = "../Scripts/script.js" type = "text/javascript" ></ script > |
7 | < link href = "../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
10 | < asp:Content ID = "Content2" ContentPlaceHolderID = "NestedContentPlaceHolder1" runat = "server" > |
12 | < asp:HyperLink ID = "HyperLink1" runat = "server" NavigateUrl = "WebForm1.aspx" >WebForm1</ asp:HyperLink > |
13 | < asp:HyperLink ID = "HyperLink2" runat = "server" NavigateUrl = "../Sample2/Sample21/WebForm2.aspx" >WebForm2</ asp:HyperLink > |
【WebForm2.aspx】
1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Sample/NestedMasterPage1.master" |
2 | AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="WebApplication1.Sample2.Sample21.WebForm2" %> |
4 | < asp:Content ID = "Content1" ContentPlaceHolderID = "Nestedhead" runat = "server" > |
6 | < script src = "../../Scripts/script.js" type = "text/javascript" ></ script > |
7 | < link href = "../../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
10 | < asp:Content ID = "Content2" ContentPlaceHolderID = "NestedContentPlaceHolder1" runat = "server" > |
12 | < asp:HyperLink ID = "HyperLink1" runat = "server" NavigateUrl = "../../Sample/WebForm1.aspx" >WebForm1</ asp:HyperLink > |
13 | < asp:HyperLink ID = "HyperLink2" runat = "server" NavigateUrl = "WebForm2.aspx" >WebForm2</ asp:HyperLink > |
【実行したWebForm1.aspxのソース】
7 | < script src = "../Scripts/script.js" type = "text/javascript" ></ script > |
8 | < link href = "../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
12 | < script src = "../Scripts/script.js" type = "text/javascript" ></ script > |
13 | < link href = "../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
17 | < script src = "../Scripts/script.js" type = "text/javascript" ></ script > |
18 | < link href = "../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
23 | < form method = "post" action = "WebForm1.aspx" id = "form1" > |
24 | < div class = "aspNetHidden" > |
25 | < input type = "hidden" name = "__VIEWSTATE" id = "__VIEWSTATE" value = "/wEPDwUJMTg0MzMwMDU2ZGTiSw70adm3ECCVM8grLanlWwO10ZEHFD/N9RZ5WsNe5Q==" /> |
30 | < a id = "HyperLink1" href = "WebForm1.aspx" >WebForm1</ a > |
31 | < a id = "HyperLink2" href = "../Sample2/Sample21/WebForm2.aspx" >WebForm2</ a > |
35 | < a id = "ContentPlaceHolder1_HyperLink1" href = "WebForm1.aspx" >WebForm1</ a > |
36 | < a id = "ContentPlaceHolder1_HyperLink2" href = "../Sample2/Sample21/WebForm2.aspx" >WebForm2</ a > |
40 | < a id = "ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink1" href = "WebForm1.aspx" >WebForm1</ a > |
41 | < a id = "ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink2" href = "../Sample2/Sample21/WebForm2.aspx" >WebForm2</ a > |
WebForm1.aspxのソースに関しては、マスターページも同じ階層にあるから、記述したパスと実行時のパスも全く一緒だね。
気になるのは次のWebForm2.aspxのソース。
確認してみる。
パスが変わってるところに★マークをつけてみた。
【実行したWebForm2.aspxのソース】
7 | < script src = "../Scripts/script.js" type = "text/javascript" ></ script > |
8 | ★ < link href = "../../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
12 | < script src = "../Scripts/script.js" type = "text/javascript" ></ script > |
13 | < link href = "../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
17 | < script src = "../../Scripts/script.js" type = "text/javascript" ></ script > |
18 | < link href = "../../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
23 | < form method = "post" action = "WebForm2.aspx" id = "form1" > |
24 | < div class = "aspNetHidden" > |
25 | < input type = "hidden" name = "__VIEWSTATE" id = "__VIEWSTATE" value = "/wEPDwUJMTg0MzMwMDU2ZGTJktGqFzpg+N5piwFRa8H6tb1fbs57vBnk5tlCg/+kFg==" /> |
30 | ★ < a id = "HyperLink1" href = "../../Sample/WebForm1.aspx" >WebForm1</ a > |
31 | ★ < a id = "HyperLink2" href = "WebForm2.aspx" >WebForm2</ a > |
35 | ★ < a id = "ContentPlaceHolder1_HyperLink1" href = "../../Sample/WebForm1.aspx" >WebForm1</ a > |
36 | ★ < a id = "ContentPlaceHolder1_HyperLink2" href = "WebForm2.aspx" >WebForm2</ a > |
40 | < a id = "ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink1" href = "../../Sample/WebForm1.aspx" >WebForm1</ a > |
41 | < a id = "ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink2" href = "WebForm2.aspx" >WebForm2</ a > |
おぉ。
aタグのhrefに関してはマスターページからの相対パスがちゃんとWebForm2.aspxからの相対パスに変わってる!
すげー。
でも、スクリプトファイルとスタイルシートのパスがそのままの部分があるなぁ。
いろいろ調べてみると~(チルダ)というものがあるらしい。
Web アプリケーションのルートを示すものらしいので、Webフォームの場所に関係なく相対パスを生成することができるみたい。
パスの部分を以下のように修正して、さっそく実行してみる。
1 | < script src = "~/Scripts/script.js" type = "text/javascript" ></ script > |
2 | < link href = "~/Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
1 | < asp:HyperLink ID = "HyperLink1" runat = "server" NavigateUrl = "~/Sample/WebForm1.aspx" >WebForm1</ asp:HyperLink > |
2 | < asp:HyperLink ID = "HyperLink2" runat = "server" NavigateUrl = "~/Sample2/Sample21/WebForm2.aspx" >WebForm2</ asp:HyperLink > |
パスが変わってるところに★マークをつけてみた。
【実行したWebForm1.aspxのソース】
7 | < script src = "~/Scripts/script.js" type = "text/javascript" ></ script > |
8 | ★ < link href = "../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
12 | < script src = "~/Scripts/script.js" type = "text/javascript" ></ script > |
13 | < link href = "~/Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
17 | < script src = "~/Scripts/script.js" type = "text/javascript" ></ script > |
18 | < link href = "~/Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
23 | < form method = "post" action = "WebForm1.aspx" id = "form1" > |
24 | < div class = "aspNetHidden" > |
25 | < input type = "hidden" name = "__VIEWSTATE" id = "__VIEWSTATE" value = "/wEPDwUJMTg0MzMwMDU2ZGTiSw70adm3ECCVM8grLanlWwO10ZEHFD/N9RZ5WsNe5Q==" /> |
30 | ★ < a id = "HyperLink1" href = "WebForm1.aspx" >WebForm1</ a > |
31 | ★ < a id = "HyperLink2" href = "../Sample2/Sample21/WebForm2.aspx" >WebForm2</ a > |
35 | ★ < a id = "ContentPlaceHolder1_HyperLink1" href = "WebForm1.aspx" >WebForm1</ a > |
36 | ★ < a id = "ContentPlaceHolder1_HyperLink2" href = "../Sample2/Sample21/WebForm2.aspx" >WebForm2</ a > |
40 | ★ < a id = "ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink1" href = "WebForm1.aspx" >WebForm1</ a > |
41 | ★ < a id = "ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink2" href = "../Sample2/Sample21/WebForm2.aspx" >WebForm2</ a > |
【実行したWebForm2.aspxのソース】
7 | < script src = "~/Scripts/script.js" type = "text/javascript" ></ script > |
8 | ★ < link href = "../../Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
12 | < script src = "~/Scripts/script.js" type = "text/javascript" ></ script > |
13 | < link href = "~/Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
17 | < script src = "~/Scripts/script.js" type = "text/javascript" ></ script > |
18 | < link href = "~/Styles/Site.css" rel = "stylesheet" type = "text/css" /> |
23 | < form method = "post" action = "WebForm2.aspx" id = "form1" > |
24 | < div class = "aspNetHidden" > |
25 | < input type = "hidden" name = "__VIEWSTATE" id = "__VIEWSTATE" value = "/wEPDwUJMTg0MzMwMDU2ZGTJktGqFzpg+N5piwFRa8H6tb1fbs57vBnk5tlCg/+kFg==" /> |
30 | ★ < a id = "HyperLink1" href = "../../Sample/WebForm1.aspx" >WebForm1</ a > |
31 | ★ < a id = "HyperLink2" href = "WebForm2.aspx" >WebForm2</ a > |
35 | ★ < a id = "ContentPlaceHolder1_HyperLink1" href = "../../Sample/WebForm1.aspx" >WebForm1</ a > |
36 | ★ < a id = "ContentPlaceHolder1_HyperLink2" href = "WebForm2.aspx" >WebForm2</ a > |
40 | ★ < a id = "ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink1" href = "../../Sample/WebForm1.aspx" >WebForm1</ a > |
41 | ★ < a id = "ContentPlaceHolder1_NestedContentPlaceHolder1_HyperLink2" href = "WebForm2.aspx" >WebForm2</ a > |
うーん。
変わってるところと変わってないところがある。
変わってるところをピックアップすると・・・
1.マスターページ「Site1.Master」の内に記載したhref部分
2.aタグのhref部分
他は変わらないなぁ。
なんでだろう。
いろいろ調べていると以下のようなルールがあることが判明。
1.scriptタグのsrcの~(チルダ)は変換されない。
2.一番上位のマスターページの内のContentPlaceHolderの~(チルダ)は変換されない。
何か手はないだろうか。
・・・・・あった!!!
以下のように書けばいいみたい。
1 | < script src = "<%= this.ResolveClientUrl(" ~/Scripts/script.js") %>" type="text/javascript"></ script > |
変わらなかった部分を全て書き換えて実行してみた。
実行した結果・・・
全部変わったー!!!
よーし!
これで相対パスの問題は解決だー。
とりあえず~(チルダ)とthis.ResolveClientUrlを使えばなんとかなるな!
もう一つ注意点として、~(チルダ)が変換されるのはあくまでサーバーコントロール内で記載されているパスのみとのこと。
<a href=”~/WebForm2.aspx”></a>のようなただのHTMLコントロールでは変換されないので、気をつけよう。